From 0daaa63d4b2ec6d3aae8956e7f64db08c044160f Mon Sep 17 00:00:00 2001 From: Francis Hilaire Date: Tue, 9 Jan 2024 21:36:26 +0100 Subject: [PATCH] Use messenger to be able to make Stripe API call in the admin --- UPGRADE.md | 24 ++++++ psalm.xml | 6 +- .../StateMachine/CancelOrderProcessorSpec.php | 74 ++++++++-------- .../CaptureAuthorizedOrderProcessorSpec.php | 52 ++++++++++++ .../CompleteAuthorizedOrderProcessorSpec.php | 84 ------------------- .../StateMachine/RefundOrderProcessorSpec.php | 61 +++----------- src/Command/CancelPayment.php | 20 +++++ src/Command/CaptureAuthorizedPayment.php | 20 +++++ .../PaymentIdAwareCommandInterface.php | 10 +++ src/Command/RefundPayment.php | 20 +++++ .../AbstractPayumPaymentHandler.php} | 38 ++++++--- src/CommandHandler/CancelPaymentHandler.php | 50 +++++++++++ .../CaptureAuthorizedPaymentHandler.php} | 24 ++++-- src/CommandHandler/RefundPaymentHandler.php | 50 +++++++++++ src/Resources/config/config.yaml | 2 +- src/Resources/config/services.yaml | 3 +- .../config/services/command_handlers.yaml | 43 ++++++++++ .../config/services/state_machine.yaml | 18 ++-- src/StateMachine/CancelOrderProcessor.php | 33 ++++---- .../CaptureAuthorizedOrderProcessor.php | 33 ++++++++ src/StateMachine/RefundOrderProcessor.php | 34 +++----- 21 files changed, 449 insertions(+), 250 deletions(-) create mode 100644 spec/StateMachine/CaptureAuthorizedOrderProcessorSpec.php delete mode 100644 spec/StateMachine/CompleteAuthorizedOrderProcessorSpec.php create mode 100644 src/Command/CancelPayment.php create mode 100644 src/Command/CaptureAuthorizedPayment.php create mode 100644 src/Command/PaymentIdAwareCommandInterface.php create mode 100644 src/Command/RefundPayment.php rename src/{StateMachine/AbstractOrderProcessor.php => CommandHandler/AbstractPayumPaymentHandler.php} (57%) create mode 100644 src/CommandHandler/CancelPaymentHandler.php rename src/{StateMachine/CompleteAuthorizedOrderProcessor.php => CommandHandler/CaptureAuthorizedPaymentHandler.php} (54%) create mode 100644 src/CommandHandler/RefundPaymentHandler.php create mode 100644 src/Resources/config/services/command_handlers.yaml create mode 100644 src/StateMachine/CaptureAuthorizedOrderProcessor.php diff --git a/UPGRADE.md b/UPGRADE.md index 200de72..8c99b91 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -1,3 +1,27 @@ +# UPGRADE FROM `v2.0.8` to `v2.0.9` + +This class has been renamed : + +- `\FluxSE\SyliusPayumStripePlugin\StateMachine\CompleteAuthorizedOrderProcessor` + to `\FluxSE\SyliusPayumStripePlugin\StateMachine\CaptureAuthorizedOrderProcessor` + +This service has been renamed : + +- `flux_se.sylius_payum_stripe.state_machine.complete_authorized` + to `flux_se.sylius_payum_stripe.state_machine.capture_authorized` + +# UPGRADE FROM `v2.0.7` to `v2.0.8` + +This class has been renamed : + +- `\FluxSE\SyliusPayumStripePlugin\StateMachine\CancelAuthorizedOrderProcessor` + to `\FluxSE\SyliusPayumStripePlugin\StateMachine\CancelOrderProcessor` + +This service has been renamed : + +- `flux_se.sylius_payum_stripe.state_machine.cancel_authorized` + to `flux_se.sylius_payum_stripe.state_machine.cancel` + # UPGRADE FROM `v1.2` TO `v2.0.0` You will have to create or edit the configuration file : diff --git a/psalm.xml b/psalm.xml index 7b38cbe..274b139 100644 --- a/psalm.xml +++ b/psalm.xml @@ -42,13 +42,13 @@ - + - + @@ -59,7 +59,7 @@ - + diff --git a/spec/StateMachine/CancelOrderProcessorSpec.php b/spec/StateMachine/CancelOrderProcessorSpec.php index 138f1f5..bbc17d2 100644 --- a/spec/StateMachine/CancelOrderProcessorSpec.php +++ b/spec/StateMachine/CancelOrderProcessorSpec.php @@ -4,68 +4,64 @@ namespace spec\FluxSE\SyliusPayumStripePlugin\StateMachine; -use FluxSE\SyliusPayumStripePlugin\Factory\CancelRequestFactoryInterface; -use Payum\Core\GatewayInterface; -use Payum\Core\Model\ModelAggregateInterface; -use Payum\Core\Payum; -use Payum\Core\Security\TokenFactoryInterface; -use Payum\Core\Security\TokenInterface; +use FluxSE\SyliusPayumStripePlugin\Command\CancelPayment; use PhpSpec\ObjectBehavior; use SM\Event\TransitionEvent; -use Sylius\Bundle\PayumBundle\Model\GatewayConfigInterface; use Sylius\Component\Core\Model\PaymentInterface; -use Sylius\Component\Core\Model\PaymentMethodInterface; +use Symfony\Component\Messenger\Envelope; +use Symfony\Component\Messenger\MessageBusInterface; final class CancelOrderProcessorSpec extends ObjectBehavior { - public function let( - CancelRequestFactoryInterface $cancelRequestFactory, - Payum $payum + public function let(MessageBusInterface $commandBus): void { + $this->beConstructedWith($commandBus); + } + + public function it_is_invokable_when_it_is_new( + PaymentInterface $payment, + TransitionEvent $event, + MessageBusInterface $commandBus, ): void { - $this->beConstructedWith($cancelRequestFactory, $payum); + $event->getState()->willReturn(PaymentInterface::STATE_NEW); + + $payment->getId()->willReturn(1); + + $command = new CancelPayment(1); + $commandBus->dispatch($command)->willReturn(new Envelope($command)); + + $this->__invoke($payment, $event); } - public function it_is_invokable( - Payum $payum, + public function it_is_invokable_when_is_authorized( PaymentInterface $payment, TransitionEvent $event, - PaymentMethodInterface $paymentMethod, - GatewayConfigInterface $gatewayConfig, - GatewayInterface $gateway, - TokenFactoryInterface $tokenFactory, - TokenInterface $token, - CancelRequestFactoryInterface $cancelRequestFactory, - ModelAggregateInterface $request + MessageBusInterface $commandBus ): void { - $payment->getMethod()->willReturn($paymentMethod); - $paymentMethod->getGatewayConfig()->willReturn($gatewayConfig); - $gatewayConfig->getConfig()->willReturn(['factory' => 'stripe_checkout_session']); - $gatewayName = 'stripe_checkout_session_with_sca'; - $gatewayConfig->getGatewayName()->willReturn($gatewayName); + $event->getState()->willReturn(PaymentInterface::STATE_AUTHORIZED); - $payum->getGateway($gatewayName)->willReturn($gateway); + $payment->getId()->willReturn(1); - $payum->getTokenFactory()->willReturn($tokenFactory); - $tokenFactory->createToken($gatewayName, $payment, 'payum_notify_do')->willReturn($token); + $command = new CancelPayment(1); + $commandBus->dispatch($command)->willReturn(new Envelope($command)); - $request->beConstructedWith([$token]); - $cancelRequestFactory->createNewWithToken($token)->willReturn($request); + $this->__invoke($payment, $event); + } - $gateway->execute($request)->shouldBeCalled(); + public function it_do_nothing_when_it_is_completed( + PaymentInterface $payment, + TransitionEvent $event + ): void { + $event->getState()->willReturn(PaymentInterface::STATE_COMPLETED); $this->__invoke($payment, $event); } - public function it_do_nothing_when_gateway_is_unknown( + public function it_do_nothing_when_it_is_refunded( PaymentInterface $payment, - TransitionEvent $event, - PaymentMethodInterface $paymentMethod, - GatewayConfigInterface $gatewayConfig + TransitionEvent $event ): void { - $payment->getMethod()->willReturn($paymentMethod); - $paymentMethod->getGatewayConfig()->willReturn($gatewayConfig); - $gatewayConfig->getConfig()->willReturn(['factory' => 'foo']); + $event->getState()->willReturn(PaymentInterface::STATE_REFUNDED); $this->__invoke($payment, $event); } diff --git a/spec/StateMachine/CaptureAuthorizedOrderProcessorSpec.php b/spec/StateMachine/CaptureAuthorizedOrderProcessorSpec.php new file mode 100644 index 0000000..530b4d2 --- /dev/null +++ b/spec/StateMachine/CaptureAuthorizedOrderProcessorSpec.php @@ -0,0 +1,52 @@ +beConstructedWith($commandBus); + } + + public function it_is_invokable( + PaymentInterface $payment, + TransitionEvent $event, + MessageBusInterface $commandBus + ): void { + $event->getState()->willReturn(PaymentInterface::STATE_AUTHORIZED); + + $payment->getId()->willReturn(1); + + $command = new CaptureAuthorizedPayment(1); + $commandBus->dispatch($command)->willReturn(new Envelope($command)); + + $this->__invoke($payment, $event); + } + + public function it_do_nothing_when_it_is_completed( + PaymentInterface $payment, + TransitionEvent $event + ): void { + $event->getState()->willReturn(PaymentInterface::STATE_COMPLETED); + + $this->__invoke($payment, $event); + } + + public function it_do_nothing_when_it_is_refunded( + PaymentInterface $payment, + TransitionEvent $event + ): void { + $event->getState()->willReturn(PaymentInterface::STATE_REFUNDED); + + $this->__invoke($payment, $event); + } +} diff --git a/spec/StateMachine/CompleteAuthorizedOrderProcessorSpec.php b/spec/StateMachine/CompleteAuthorizedOrderProcessorSpec.php deleted file mode 100644 index 9efe7b9..0000000 --- a/spec/StateMachine/CompleteAuthorizedOrderProcessorSpec.php +++ /dev/null @@ -1,84 +0,0 @@ -beConstructedWith($captureRequestFactory, $payum); - } - - public function it_is_invokable( - Payum $payum, - PaymentInterface $payment, - TransitionEvent $event, - PaymentMethodInterface $paymentMethod, - GatewayConfigInterface $gatewayConfig, - GatewayInterface $gateway, - TokenFactoryInterface $tokenFactory, - TokenInterface $token, - CaptureRequestFactoryInterface $captureRequestFactory, - ModelAggregateInterface $request - ): void { - $event->getState()->willReturn(PaymentInterface::STATE_AUTHORIZED); - - $payment->getMethod()->willReturn($paymentMethod); - $paymentMethod->getGatewayConfig()->willReturn($gatewayConfig); - $gatewayConfig->getConfig()->willReturn(['factory' => 'stripe_checkout_session']); - $gatewayName = 'stripe_checkout_session_with_sca'; - $gatewayConfig->getGatewayName()->willReturn($gatewayName); - - $payum->getGateway($gatewayName)->willReturn($gateway); - - $payum->getTokenFactory()->willReturn($tokenFactory); - $tokenFactory->createToken($gatewayName, $payment, 'payum_notify_do')->willReturn($token); - - $request->beConstructedWith([$token]); - $captureRequestFactory->createNewWithToken($token)->willReturn($request); - - $gateway->execute($request)->shouldBeCalled(); - - $this->__invoke($payment, $event); - } - - public function it_do_nothing_when_it_is_not_an_authorized_state( - PaymentInterface $payment, - TransitionEvent $event - ): void { - $event->getState()->willReturn(PaymentInterface::STATE_COMPLETED); - - $this->__invoke($payment, $event); - } - - public function it_do_nothing_when_gateway_is_unknown( - PaymentInterface $payment, - TransitionEvent $event, - PaymentMethodInterface $paymentMethod, - GatewayConfigInterface $gatewayConfig - ): void { - $event->getState()->willReturn(PaymentInterface::STATE_AUTHORIZED); - - $payment->getMethod()->willReturn($paymentMethod); - $paymentMethod->getGatewayConfig()->willReturn($gatewayConfig); - $gatewayConfig->getConfig()->willReturn(['factory' => 'foo']); - - $this->__invoke($payment, $event); - } -} diff --git a/spec/StateMachine/RefundOrderProcessorSpec.php b/spec/StateMachine/RefundOrderProcessorSpec.php index a0133a6..f376c74 100644 --- a/spec/StateMachine/RefundOrderProcessorSpec.php +++ b/spec/StateMachine/RefundOrderProcessorSpec.php @@ -4,61 +4,35 @@ namespace spec\FluxSE\SyliusPayumStripePlugin\StateMachine; -use FluxSE\SyliusPayumStripePlugin\Factory\RefundRequestFactoryInterface; -use Payum\Core\GatewayInterface; -use Payum\Core\Model\ModelAggregateInterface; -use Payum\Core\Payum; -use Payum\Core\Security\TokenFactoryInterface; -use Payum\Core\Security\TokenInterface; +use FluxSE\SyliusPayumStripePlugin\Command\RefundPayment; use PhpSpec\ObjectBehavior; use SM\Event\TransitionEvent; -use Sylius\Bundle\PayumBundle\Model\GatewayConfigInterface; use Sylius\Component\Core\Model\PaymentInterface; -use Sylius\Component\Core\Model\PaymentMethodInterface; +use Symfony\Component\Messenger\Envelope; +use Symfony\Component\Messenger\MessageBusInterface; final class RefundOrderProcessorSpec extends ObjectBehavior { - public function let( - RefundRequestFactoryInterface $refundRequestFactory, - Payum $payum - ): void { - $this->beConstructedWith($refundRequestFactory, $payum); + public function let(MessageBusInterface $commandBus): void { + $this->beConstructedWith($commandBus); } public function it_is_invokable( - Payum $payum, PaymentInterface $payment, TransitionEvent $event, - PaymentMethodInterface $paymentMethod, - GatewayConfigInterface $gatewayConfig, - GatewayInterface $gateway, - TokenFactoryInterface $tokenFactory, - TokenInterface $token, - RefundRequestFactoryInterface $refundRequestFactory, - ModelAggregateInterface $request + MessageBusInterface $commandBus ): void { $event->getState()->willReturn(PaymentInterface::STATE_COMPLETED); - $payment->getMethod()->willReturn($paymentMethod); - $paymentMethod->getGatewayConfig()->willReturn($gatewayConfig); - $gatewayConfig->getConfig()->willReturn(['factory' => 'stripe_checkout_session']); - $gatewayName = 'stripe_checkout_session_with_sca'; - $gatewayConfig->getGatewayName()->willReturn($gatewayName); - - $payum->getGateway($gatewayName)->willReturn($gateway); - - $payum->getTokenFactory()->willReturn($tokenFactory); - $tokenFactory->createToken($gatewayName, $payment, 'payum_notify_do')->willReturn($token); - - $request->beConstructedWith([$token]); - $refundRequestFactory->createNewWithToken($token)->willReturn($request); + $payment->getId()->willReturn(1); - $gateway->execute($request)->shouldBeCalled(); + $command = new RefundPayment(1); + $commandBus->dispatch($command)->willReturn(new Envelope($command)); $this->__invoke($payment, $event); } - public function it_do_nothing_when_it_is_not_a_completed_state( + public function it_do_nothing_when_it_is_authorized( PaymentInterface $payment, TransitionEvent $event ): void { @@ -66,19 +40,4 @@ public function it_do_nothing_when_it_is_not_a_completed_state( $this->__invoke($payment, $event); } - - public function it_do_nothing_when_gateway_is_unknown( - PaymentInterface $payment, - TransitionEvent $event, - PaymentMethodInterface $paymentMethod, - GatewayConfigInterface $gatewayConfig - ): void { - $event->getState()->willReturn(PaymentInterface::STATE_COMPLETED); - - $payment->getMethod()->willReturn($paymentMethod); - $paymentMethod->getGatewayConfig()->willReturn($gatewayConfig); - $gatewayConfig->getConfig()->willReturn(['factory' => 'foo']); - - $this->__invoke($payment, $event); - } } diff --git a/src/Command/CancelPayment.php b/src/Command/CancelPayment.php new file mode 100644 index 0000000..4192d7d --- /dev/null +++ b/src/Command/CancelPayment.php @@ -0,0 +1,20 @@ +paymentId = $paymentId; + } + + public function getPaymentId(): int + { + return $this->paymentId; + } +} diff --git a/src/Command/CaptureAuthorizedPayment.php b/src/Command/CaptureAuthorizedPayment.php new file mode 100644 index 0000000..46ae9cd --- /dev/null +++ b/src/Command/CaptureAuthorizedPayment.php @@ -0,0 +1,20 @@ +paymentId = $paymentId; + } + + public function getPaymentId(): int + { + return $this->paymentId; + } +} diff --git a/src/Command/PaymentIdAwareCommandInterface.php b/src/Command/PaymentIdAwareCommandInterface.php new file mode 100644 index 0000000..7cca670 --- /dev/null +++ b/src/Command/PaymentIdAwareCommandInterface.php @@ -0,0 +1,10 @@ +paymentId = $paymentId; + } + + public function getPaymentId(): int + { + return $this->paymentId; + } +} diff --git a/src/StateMachine/AbstractOrderProcessor.php b/src/CommandHandler/AbstractPayumPaymentHandler.php similarity index 57% rename from src/StateMachine/AbstractOrderProcessor.php rename to src/CommandHandler/AbstractPayumPaymentHandler.php index 0ca20b3..5b93d4f 100644 --- a/src/StateMachine/AbstractOrderProcessor.php +++ b/src/CommandHandler/AbstractPayumPaymentHandler.php @@ -2,32 +2,48 @@ declare(strict_types=1); -namespace FluxSE\SyliusPayumStripePlugin\StateMachine; +namespace FluxSE\SyliusPayumStripePlugin\CommandHandler; +use FluxSE\SyliusPayumStripePlugin\Command\PaymentIdAwareCommandInterface; use Payum\Core\Payum; use Payum\Core\Security\TokenFactoryInterface; use Payum\Core\Security\TokenInterface; -use SM\Event\TransitionEvent; use Sylius\Bundle\PayumBundle\Model\GatewayConfigInterface; use Sylius\Component\Core\Model\PaymentInterface; use Sylius\Component\Core\Model\PaymentMethodInterface; +use Sylius\Component\Core\Repository\PaymentRepositoryInterface; -abstract class AbstractOrderProcessor +abstract class AbstractPayumPaymentHandler { - public const HANDLEABLE_GATEWAYS = [ - 'stripe_checkout_session', - 'stripe_js', - ]; + /** @var PaymentRepositoryInterface */ + private $paymentRepository; /** @var Payum */ protected $payum; - public function __construct(Payum $payum) - { + /** @var string[] */ + protected array $supportedGateways; + + /** + * @param string[] $supportedGateways + */ + public function __construct( + PaymentRepositoryInterface $paymentRepository, + Payum $payum, + array $supportedGateways + ) { + $this->paymentRepository = $paymentRepository; $this->payum = $payum; + $this->supportedGateways = $supportedGateways; } - abstract public function __invoke(PaymentInterface $payment, TransitionEvent $event): void; + protected function retrievePayment(PaymentIdAwareCommandInterface $command): ?PaymentInterface + { + /** @var PaymentInterface|null $payment */ + $payment = $this->paymentRepository->find($command->getPaymentId()); + + return $payment; + } protected function getGatewayNameFromPayment(PaymentInterface $payment): ?string { @@ -46,7 +62,7 @@ protected function getGatewayNameFromPayment(PaymentInterface $payment): ?string $config = $gatewayConfig->getConfig(); $factory = $config['factory'] ?? $gatewayConfig->getFactoryName(); - if (false === in_array($factory, self::HANDLEABLE_GATEWAYS, true)) { + if (false === in_array($factory, $this->supportedGateways, true)) { return null; } diff --git a/src/CommandHandler/CancelPaymentHandler.php b/src/CommandHandler/CancelPaymentHandler.php new file mode 100644 index 0000000..c562036 --- /dev/null +++ b/src/CommandHandler/CancelPaymentHandler.php @@ -0,0 +1,50 @@ +cancelRequestFactory = $cancelRequestFactory; + + parent::__construct($paymentRepository, $payum, $supportedGateways); + } + + public function __invoke(CancelPayment $command): void + { + $payment = $this->retrievePayment($command); + if (null === $payment) { + return; + } + + $gatewayName = $this->getGatewayNameFromPayment($payment); + + if (null === $gatewayName) { + return; + } + + $gateway = $this->payum->getGateway($gatewayName); + $token = $this->buildToken($gatewayName, $payment); + + $cancelRequest = $this->cancelRequestFactory->createNewWithToken($token); + $gateway->execute($cancelRequest); + } +} diff --git a/src/StateMachine/CompleteAuthorizedOrderProcessor.php b/src/CommandHandler/CaptureAuthorizedPaymentHandler.php similarity index 54% rename from src/StateMachine/CompleteAuthorizedOrderProcessor.php rename to src/CommandHandler/CaptureAuthorizedPaymentHandler.php index fbca964..55ca328 100644 --- a/src/StateMachine/CompleteAuthorizedOrderProcessor.php +++ b/src/CommandHandler/CaptureAuthorizedPaymentHandler.php @@ -2,31 +2,38 @@ declare(strict_types=1); -namespace FluxSE\SyliusPayumStripePlugin\StateMachine; +namespace FluxSE\SyliusPayumStripePlugin\CommandHandler; +use FluxSE\SyliusPayumStripePlugin\Command\CaptureAuthorizedPayment; use FluxSE\SyliusPayumStripePlugin\Factory\CaptureRequestFactoryInterface; use Payum\Core\Payum; use Payum\Core\Reply\ReplyInterface; -use SM\Event\TransitionEvent; -use Sylius\Component\Core\Model\PaymentInterface; +use Sylius\Component\Core\Repository\PaymentRepositoryInterface; use Webmozart\Assert\Assert; -final class CompleteAuthorizedOrderProcessor extends AbstractOrderProcessor +final class CaptureAuthorizedPaymentHandler extends AbstractPayumPaymentHandler { /** @var CaptureRequestFactoryInterface */ private $captureRequestFactory; + /** + * @param string[] $supportedGateways + */ public function __construct( CaptureRequestFactoryInterface $captureRequestFactory, - Payum $payum + PaymentRepositoryInterface $paymentRepository, + Payum $payum, + array $supportedGateways ) { $this->captureRequestFactory = $captureRequestFactory; - parent::__construct($payum); + + parent::__construct($paymentRepository, $payum, $supportedGateways); } - public function __invoke(PaymentInterface $payment, TransitionEvent $event): void + public function __invoke(CaptureAuthorizedPayment $command): void { - if (PaymentInterface::STATE_AUTHORIZED !== $event->getState()) { + $payment = $this->retrievePayment($command); + if (null === $payment) { return; } @@ -42,6 +49,7 @@ public function __invoke(PaymentInterface $payment, TransitionEvent $event): voi $request = $this->captureRequestFactory->createNewWithToken($token); $reply = $gateway->execute($request); + // No reply must be done by this Capture request, if there is it means that a normal Capture has been done. Assert::notInstanceOf($reply, ReplyInterface::class); } } diff --git a/src/CommandHandler/RefundPaymentHandler.php b/src/CommandHandler/RefundPaymentHandler.php new file mode 100644 index 0000000..1e6777e --- /dev/null +++ b/src/CommandHandler/RefundPaymentHandler.php @@ -0,0 +1,50 @@ +refundRequestFactory = $refundRequestFactory; + + parent::__construct($paymentRepository, $payum, $supportedGateways); + } + + public function __invoke(RefundPayment $command): void + { + $payment = $this->retrievePayment($command); + if (null === $payment) { + return; + } + + $gatewayName = $this->getGatewayNameFromPayment($payment); + + if (null === $gatewayName) { + return; + } + + $gateway = $this->payum->getGateway($gatewayName); + $token = $this->buildToken($gatewayName, $payment); + + $refundRequest = $this->refundRequestFactory->createNewWithToken($token); + $gateway->execute($refundRequest); + } +} diff --git a/src/Resources/config/config.yaml b/src/Resources/config/config.yaml index 80b7ea5..a7c9a41 100644 --- a/src/Resources/config/config.yaml +++ b/src/Resources/config/config.yaml @@ -18,5 +18,5 @@ winzou_state_machine: args: ["object", "event"] flux_se.sylius_payum_stripe_complete_authorized: on: ["complete"] - do: ["@flux_se.sylius_payum_stripe.state_machine.complete_authorized", "__invoke"] + do: ["@flux_se.sylius_payum_stripe.state_machine.capture_authorized", "__invoke"] args: ["object", "event"] diff --git a/src/Resources/config/services.yaml b/src/Resources/config/services.yaml index d500491..ca8f006 100644 --- a/src/Resources/config/services.yaml +++ b/src/Resources/config/services.yaml @@ -1,6 +1,7 @@ imports: + - { resource: 'services/command_handlers.yaml' } - { resource: 'services/factory.yaml' } - { resource: 'services/gateway_configuration_types.yaml' } - { resource: 'services/payum.yaml' } - { resource: 'services/providers.yaml' } - - { resource: 'services/state_machine.yaml' } \ No newline at end of file + - { resource: 'services/state_machine.yaml' } diff --git a/src/Resources/config/services/command_handlers.yaml b/src/Resources/config/services/command_handlers.yaml new file mode 100644 index 0000000..cb0d2a2 --- /dev/null +++ b/src/Resources/config/services/command_handlers.yaml @@ -0,0 +1,43 @@ +parameters: + flux_se.sylius_payum_stripe.command_handler.supported_gateways: + - stripe_checkout_session + - stripe_js + +services: + + FluxSE\SyliusPayumStripePlugin\CommandHandler\AbstractPayumPaymentHandler: + abstract: true + arguments: + $paymentRepository: '@sylius.repository.payment' + $payum: '@payum' + $supportedGateways: '%flux_se.sylius_payum_stripe.command_handler.supported_gateways%' + + flux_se.sylius_payum_stripe.command_handler.refund: + public: true + parent: FluxSE\SyliusPayumStripePlugin\CommandHandler\AbstractPayumPaymentHandler + class: FluxSE\SyliusPayumStripePlugin\CommandHandler\RefundPaymentHandler + arguments: + $refundRequestFactory: '@flux_se.sylius_payum_stripe.factory.refund_request' + tags: + - name: messenger.message_handler + bus: sylius.command_bus + + flux_se.sylius_payum_stripe.command_handler.cancel: + public: true + parent: FluxSE\SyliusPayumStripePlugin\CommandHandler\AbstractPayumPaymentHandler + class: FluxSE\SyliusPayumStripePlugin\CommandHandler\CancelPaymentHandler + arguments: + $cancelRequestFactory: '@flux_se.sylius_payum_stripe.factory.cancel_request' + tags: + - name: messenger.message_handler + bus: sylius.command_bus + + flux_se.sylius_payum_stripe.command_handler.capture_authorized: + public: true + parent: FluxSE\SyliusPayumStripePlugin\CommandHandler\AbstractPayumPaymentHandler + class: FluxSE\SyliusPayumStripePlugin\CommandHandler\CaptureAuthorizedPaymentHandler + arguments: + $captureRequestFactory: '@flux_se.sylius_payum_stripe.factory.capture_request' + tags: + - name: messenger.message_handler + bus: sylius.command_bus diff --git a/src/Resources/config/services/state_machine.yaml b/src/Resources/config/services/state_machine.yaml index ab97d29..4676790 100644 --- a/src/Resources/config/services/state_machine.yaml +++ b/src/Resources/config/services/state_machine.yaml @@ -1,27 +1,19 @@ services: - FluxSE\SyliusPayumStripePlugin\StateMachine\AbstractOrderProcessor: - abstract: true - arguments: - $payum: '@payum' - flux_se.sylius_payum_stripe.state_machine.refund: public: true - parent: FluxSE\SyliusPayumStripePlugin\StateMachine\AbstractOrderProcessor class: FluxSE\SyliusPayumStripePlugin\StateMachine\RefundOrderProcessor arguments: - $refundRequestFactory: '@flux_se.sylius_payum_stripe.factory.refund_request' + $commandBus: '@sylius.command_bus' flux_se.sylius_payum_stripe.state_machine.cancel: public: true - parent: FluxSE\SyliusPayumStripePlugin\StateMachine\AbstractOrderProcessor class: FluxSE\SyliusPayumStripePlugin\StateMachine\CancelOrderProcessor arguments: - $cancelRequestFactory: '@flux_se.sylius_payum_stripe.factory.cancel_request' + $commandBus: '@sylius.command_bus' - flux_se.sylius_payum_stripe.state_machine.complete_authorized: + flux_se.sylius_payum_stripe.state_machine.capture_authorized: public: true - parent: FluxSE\SyliusPayumStripePlugin\StateMachine\AbstractOrderProcessor - class: FluxSE\SyliusPayumStripePlugin\StateMachine\CompleteAuthorizedOrderProcessor + class: FluxSE\SyliusPayumStripePlugin\StateMachine\CaptureAuthorizedOrderProcessor arguments: - $captureRequestFactory: '@flux_se.sylius_payum_stripe.factory.capture_request' + $commandBus: '@sylius.command_bus' diff --git a/src/StateMachine/CancelOrderProcessor.php b/src/StateMachine/CancelOrderProcessor.php index 58b563a..0ad3b18 100644 --- a/src/StateMachine/CancelOrderProcessor.php +++ b/src/StateMachine/CancelOrderProcessor.php @@ -4,36 +4,35 @@ namespace FluxSE\SyliusPayumStripePlugin\StateMachine; -use FluxSE\SyliusPayumStripePlugin\Factory\CancelRequestFactoryInterface; -use Payum\Core\Payum; +use FluxSE\SyliusPayumStripePlugin\Command\CancelPayment; use SM\Event\TransitionEvent; use Sylius\Component\Core\Model\PaymentInterface; +use Symfony\Component\Messenger\MessageBusInterface; +use Webmozart\Assert\Assert; -final class CancelOrderProcessor extends AbstractOrderProcessor +final class CancelOrderProcessor { - /** @var CancelRequestFactoryInterface */ - private $cancelRequestFactory; + /** @var MessageBusInterface */ + private $commandBus; public function __construct( - CancelRequestFactoryInterface $cancelRequestFactory, - Payum $payum + MessageBusInterface $commandBus ) { - $this->cancelRequestFactory = $cancelRequestFactory; - parent::__construct($payum); + $this->commandBus = $commandBus; } public function __invoke(PaymentInterface $payment, TransitionEvent $event): void { - $gatewayName = $this->getGatewayNameFromPayment($payment); - - if (null === $gatewayName) { + if (false === in_array($event->getState(), [ + PaymentInterface::STATE_NEW, + PaymentInterface::STATE_AUTHORIZED, + ], true)) { return; } - $gateway = $this->payum->getGateway($gatewayName); - $token = $this->buildToken($gatewayName, $payment); - - $cancelRequest = $this->cancelRequestFactory->createNewWithToken($token); - $gateway->execute($cancelRequest); + /** @var int|null $paymentId */ + $paymentId = $payment->getId(); + Assert::notNull($paymentId); + $this->commandBus->dispatch(new CancelPayment($paymentId)); } } diff --git a/src/StateMachine/CaptureAuthorizedOrderProcessor.php b/src/StateMachine/CaptureAuthorizedOrderProcessor.php new file mode 100644 index 0000000..fc673b8 --- /dev/null +++ b/src/StateMachine/CaptureAuthorizedOrderProcessor.php @@ -0,0 +1,33 @@ +commandBus = $commandBus; + } + + public function __invoke(PaymentInterface $payment, TransitionEvent $event): void + { + if (PaymentInterface::STATE_AUTHORIZED !== $event->getState()) { + return; + } + + /** @var int|null $paymentId */ + $paymentId = $payment->getId(); + Assert::notNull($paymentId); + $this->commandBus->dispatch(new CaptureAuthorizedPayment($paymentId)); + } +} diff --git a/src/StateMachine/RefundOrderProcessor.php b/src/StateMachine/RefundOrderProcessor.php index 5f9cc37..cdb8a19 100644 --- a/src/StateMachine/RefundOrderProcessor.php +++ b/src/StateMachine/RefundOrderProcessor.php @@ -4,22 +4,19 @@ namespace FluxSE\SyliusPayumStripePlugin\StateMachine; -use FluxSE\SyliusPayumStripePlugin\Factory\RefundRequestFactoryInterface; -use Payum\Core\Payum; +use FluxSE\SyliusPayumStripePlugin\Command\RefundPayment; use SM\Event\TransitionEvent; use Sylius\Component\Core\Model\PaymentInterface; +use Symfony\Component\Messenger\MessageBusInterface; +use Webmozart\Assert\Assert; -final class RefundOrderProcessor extends AbstractOrderProcessor +final class RefundOrderProcessor { - /** @var RefundRequestFactoryInterface */ - private $refundRequestFactory; + /** @var MessageBusInterface */ + private $commandBus; - public function __construct( - RefundRequestFactoryInterface $refundRequestFactory, - Payum $payum - ) { - $this->refundRequestFactory = $refundRequestFactory; - parent:: __construct($payum); + public function __construct(MessageBusInterface $commandBus) { + $this->commandBus = $commandBus; } public function __invoke(PaymentInterface $payment, TransitionEvent $event): void @@ -28,16 +25,9 @@ public function __invoke(PaymentInterface $payment, TransitionEvent $event): voi return; } - $gatewayName = $this->getGatewayNameFromPayment($payment); - - if (null === $gatewayName) { - return; - } - - $gateway = $this->payum->getGateway($gatewayName); - $token = $this->buildToken($gatewayName, $payment); - - $refundRequest = $this->refundRequestFactory->createNewWithToken($token); - $gateway->execute($refundRequest); + /** @var int|null $paymentId */ + $paymentId = $payment->getId(); + Assert::notNull($paymentId); + $this->commandBus->dispatch(new RefundPayment($paymentId)); } }