1919use Sylius \Abstraction \StateMachine \WinzouStateMachineAdapter ;
2020use Sylius \Component \Core \Model \PaymentInterface ;
2121use Sylius \Component \Core \OrderCheckoutTransitions ;
22+ use Sylius \Component \Order \Processor \OrderProcessorInterface ;
23+ use Sylius \PayPalPlugin \Exception \PaymentAmountMismatchException ;
2224use Sylius \PayPalPlugin \Manager \PaymentStateManagerInterface ;
2325use Sylius \PayPalPlugin \Provider \OrderProviderInterface ;
26+ use Sylius \PayPalPlugin \Verifier \PaymentAmountVerifierInterface ;
2427use Symfony \Component \HttpFoundation \JsonResponse ;
2528use Symfony \Component \HttpFoundation \Request ;
2629use Symfony \Component \HttpFoundation \Response ;
@@ -34,6 +37,8 @@ public function __construct(
3437 private readonly OrderProviderInterface $ orderProvider ,
3538 private readonly FactoryInterface |StateMachineInterface $ stateMachine ,
3639 private readonly ObjectManager $ orderManager ,
40+ private readonly ?PaymentAmountVerifierInterface $ paymentAmountVerifier = null ,
41+ private readonly ?OrderProcessorInterface $ orderProcessor = null ,
3742 ) {
3843 if ($ this ->stateMachine instanceof FactoryInterface) {
3944 trigger_deprecation (
@@ -46,6 +51,22 @@ public function __construct(
4651 ),
4752 );
4853 }
54+ if (null === $ this ->paymentAmountVerifier ) {
55+ trigger_deprecation (
56+ 'sylius/paypal-plugin ' ,
57+ '1.6 ' ,
58+ 'Not passing an instance of "%s" as the fifth argument is deprecated and will be prohibited in 3.0. ' ,
59+ PaymentAmountVerifierInterface::class,
60+ );
61+ }
62+ if (null === $ this ->orderProcessor ) {
63+ trigger_deprecation (
64+ 'sylius/paypal-plugin ' ,
65+ '1.6 ' ,
66+ 'Not passing an instance of "%s" as the sixth argument is deprecated and will be prohibited in 3.0. ' ,
67+ OrderProcessorInterface::class,
68+ );
69+ }
4970 }
5071
5172 public function __invoke (Request $ request ): Response
@@ -56,6 +77,26 @@ public function __invoke(Request $request): Response
5677 /** @var PaymentInterface $payment */
5778 $ payment = $ order ->getLastPayment (PaymentInterface::STATE_PROCESSING );
5879
80+ try {
81+ if ($ this ->paymentAmountVerifier !== null ) {
82+ $ this ->paymentAmountVerifier ->verify ($ payment );
83+ } else {
84+ $ this ->verify ($ payment );
85+ }
86+ } catch (PaymentAmountMismatchException ) {
87+ $ this ->paymentStateManager ->cancel ($ payment );
88+ $ order ->removePayment ($ payment );
89+
90+ if (null === $ this ->orderProcessor ) {
91+ throw new \RuntimeException ('Order processor is required to process the order. ' );
92+ }
93+ $ this ->orderProcessor ->process ($ order );
94+
95+ return new JsonResponse ([
96+ 'return_url ' => $ this ->router ->generate ('sylius_shop_checkout_complete ' , [], UrlGeneratorInterface::ABSOLUTE_URL ),
97+ ]);
98+ }
99+
59100 $ this ->paymentStateManager ->complete ($ payment );
60101
61102 $ this ->getStateMachine ()->apply ($ order , OrderCheckoutTransitions::GRAPH , OrderCheckoutTransitions::TRANSITION_SELECT_PAYMENT );
@@ -78,4 +119,20 @@ private function getStateMachine(): StateMachineInterface
78119
79120 return $ this ->stateMachine ;
80121 }
122+
123+ private function verify (PaymentInterface $ payment ): void
124+ {
125+ $ totalAmount = $ this ->getTotalPaymentAmountFromPaypal ($ payment );
126+
127+ if ($ payment ->getOrder ()->getTotal () !== $ totalAmount ) {
128+ throw new PaymentAmountMismatchException ();
129+ }
130+ }
131+
132+ private function getTotalPaymentAmountFromPaypal (PaymentInterface $ payment ): int
133+ {
134+ $ details = $ payment ->getDetails ();
135+
136+ return $ details ['payment_amount ' ] ?? 0 ;
137+ }
81138}
0 commit comments