diff --git a/spec/Enabler/PayPalPaymentMethodEnablerSpec.php b/spec/Enabler/PayPalPaymentMethodEnablerSpec.php new file mode 100644 index 00000000..250429c8 --- /dev/null +++ b/spec/Enabler/PayPalPaymentMethodEnablerSpec.php @@ -0,0 +1,84 @@ +beConstructedWith($client, 'http://base-url.com', $paymentMethodManager); + } + + function it_implements_payment_method_enabler_interface(): void + { + $this->shouldImplement(PaymentMethodEnablerInterface::class); + } + + function it_enables_payment_method_if_it_has_proper_credentials_set( + Client $client, + ObjectManager $paymentMethodManager, + PaymentMethodInterface $paymentMethod, + GatewayConfigInterface $gatewayConfig, + ResponseInterface $response, + StreamInterface $body + ): void { + $paymentMethod->getGatewayConfig()->willReturn($gatewayConfig); + $gatewayConfig->getConfig()->willReturn(['merchant_id' => '123123']); + + $client->request('GET', 'http://base-url.com/seller-permissions/check/123123')->willReturn($response); + $response->getBody()->willReturn($body); + $body->getContents()->willReturn('{ "permissionsGranted": true }'); + + $paymentMethod->setEnabled(true)->shouldBeCalled(); + $paymentMethodManager->flush()->shouldBeCalled(); + + $this->enable($paymentMethod); + } + + function it_throws_exception_if_payment_method_credentials_are_not_granted( + Client $client, + ObjectManager $paymentMethodManager, + PaymentMethodInterface $paymentMethod, + GatewayConfigInterface $gatewayConfig, + ResponseInterface $response, + StreamInterface $body + ): void { + $paymentMethod->getGatewayConfig()->willReturn($gatewayConfig); + $gatewayConfig->getConfig()->willReturn(['merchant_id' => '123123']); + + $client->request('GET', 'http://base-url.com/seller-permissions/check/123123')->willReturn($response); + $response->getBody()->willReturn($body); + $body->getContents()->willReturn('{ "permissionsGranted": false }'); + + $paymentMethod->setEnabled(true)->shouldNotBeCalled(); + $paymentMethodManager->flush()->shouldNotBeCalled(); + + $this + ->shouldThrow(PaymentMethodCouldNotBeEnabledException::class) + ->during('enable', [$paymentMethod]) + ; + } +} diff --git a/spec/Onboarding/Processor/BasicOnboardingProcessorSpec.php b/spec/Onboarding/Processor/BasicOnboardingProcessorSpec.php index 27e310a1..0c6efe0f 100644 --- a/spec/Onboarding/Processor/BasicOnboardingProcessorSpec.php +++ b/spec/Onboarding/Processor/BasicOnboardingProcessorSpec.php @@ -81,6 +81,66 @@ function it_processes_onboarding_for_supported_payment_method_and_request( $this->process($paymentMethod, $request)->shouldReturn($paymentMethod); } + function it_processes_onboarding_for_supported_payment_method_with_not_granted_permissions_and_request( + ClientInterface $httpClient, + ResponseInterface $response, + StreamInterface $body, + GatewayConfigInterface $gatewayConfig, + PaymentMethodInterface $paymentMethod, + Request $request + ): void { + $gatewayConfig->getFactoryName()->willReturn('sylius.pay_pal'); + $gatewayConfig->getConfig()->willReturn( + [ + 'client_id' => 'CLIENT-ID', + 'client_secret' => 'CLIENT-SECRET', + 'sylius_merchant_id' => 'SYLIUS-MERCHANT-ID', + 'merchant_id' => 'MERCHANT-ID', + ] + ); + + $paymentMethod->getGatewayConfig()->willReturn($gatewayConfig); + + $request->query = new ParameterBag(['onboarding_id' => 'ONBOARDING-ID', 'permissionsGranted' => false]); + + $httpClient + ->request( + 'GET', + 'https://paypal.facilitator.com/partner-referrals/check/ONBOARDING-ID', + [ + 'headers' => [ + 'Content-Type' => 'application/json', + 'Accept' => 'application/json', + ], + ] + ) + ->willReturn($response) + ; + + $response->getBody()->willReturn($body); + $body->getContents()->willReturn( + '{"client_id":"CLIENT-ID", + "client_secret":"CLIENT-SECRET", + "sylius_merchant_id":"SYLIUS-MERCHANT-ID", + "merchant_id":"MERCHANT-ID", + "partner_attribution_id":"ATTRIBUTION-ID"}' + ); + + $paymentMethod->setEnabled(false)->shouldBeCalled(); + $gatewayConfig->setConfig( + [ + 'client_id' => 'CLIENT-ID', + 'client_secret' => 'CLIENT-SECRET', + 'onboarding_id' => 'ONBOARDING-ID', + 'sylius_merchant_id' => 'SYLIUS-MERCHANT-ID', + 'merchant_id' => 'MERCHANT-ID', + 'partner_attribution_id' => 'ATTRIBUTION-ID', + ] + )->shouldBeCalled(); + + $this->process($paymentMethod, $request)->shouldReturn($paymentMethod); + } + function it_throws_an_exception_when_trying_to_process_onboarding_for_unsupported_payment_method_or_request( PaymentMethodInterface $paymentMethod, Request $request diff --git a/src/Controller/EnableSellerAction.php b/src/Controller/EnableSellerAction.php new file mode 100644 index 00000000..ba2fe21b --- /dev/null +++ b/src/Controller/EnableSellerAction.php @@ -0,0 +1,51 @@ +paymentMethodRepository = $paymentMethodRepository; + $this->paymentMethodEnabler = $paymentMethodEnabler; + } + + public function __invoke(Request $request): Response + { + /** @var PaymentMethodInterface $paymentMethod */ + $paymentMethod = $this->paymentMethodRepository->find($request->attributes->getInt('id')); + /** @var FlashBagInterface $flashBag */ + $flashBag = $request->getSession()->getBag('flashes'); + + try { + $this->paymentMethodEnabler->enable($paymentMethod); + } catch (PaymentMethodCouldNotBeEnabledException $exception) { + $flashBag->add('error', 'sylius.pay_pal.payment_not_enabled'); + + return new RedirectResponse($request->headers->get('referer')); + } + + $flashBag->add('success', 'sylius.pay_pal.payment_enabled'); + + return new RedirectResponse($request->headers->get('referer')); + } +} diff --git a/src/Enabler/PayPalPaymentMethodEnabler.php b/src/Enabler/PayPalPaymentMethodEnabler.php new file mode 100644 index 00000000..7bc53410 --- /dev/null +++ b/src/Enabler/PayPalPaymentMethodEnabler.php @@ -0,0 +1,59 @@ +client = $client; + $this->baseUrl = $baseUrl; + $this->paymentMethodManager = $paymentMethodManager; + } + + public function enable(PaymentMethodInterface $paymentMethod): void + { + /** @var GatewayConfigInterface $gatewayConfig */ + $gatewayConfig = $paymentMethod->getGatewayConfig(); + $config = $gatewayConfig->getConfig(); + + $response = $this->client->request( + 'GET', + sprintf('%s/seller-permissions/check/%s', $this->baseUrl, (string) $config['merchant_id']) + ); + + $content = (array) json_decode($response->getBody()->getContents(), true); + if (!((bool) $content['permissionsGranted'])) { + throw new PaymentMethodCouldNotBeEnabledException(); + } + + $paymentMethod->setEnabled(true); + $this->paymentMethodManager->flush(); + } +} diff --git a/src/Enabler/PaymentMethodEnablerInterface.php b/src/Enabler/PaymentMethodEnablerInterface.php new file mode 100644 index 00000000..a0d59505 --- /dev/null +++ b/src/Enabler/PaymentMethodEnablerInterface.php @@ -0,0 +1,16 @@ +addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event): void { + /** @var PaymentMethodInterface $data */ + $data = $event->getData(); + $form = $event->getForm(); + + /** @var GatewayConfigInterface $gatewayConfig */ + $gatewayConfig = $data->getGatewayConfig(); + if ($gatewayConfig->getFactoryName() === 'sylius.pay_pal') { + $form->add('enabled', HiddenType::class, [ + 'required' => false, + 'label' => 'sylius.form.payment_method.enabled', + 'data' => $data->isEnabled(), + ]); + } + }); + } + + public function getExtendedTypes(): iterable + { + return [PaymentMethodType::class]; + } +} diff --git a/src/Onboarding/Processor/BasicOnboardingProcessor.php b/src/Onboarding/Processor/BasicOnboardingProcessor.php index 37ab1d55..e5e374cc 100644 --- a/src/Onboarding/Processor/BasicOnboardingProcessor.php +++ b/src/Onboarding/Processor/BasicOnboardingProcessor.php @@ -38,9 +38,10 @@ public function process( /** @var GatewayConfig $gatewayConfig */ Assert::notNull($gatewayConfig); + $onboardingId = (string) $request->query->get('onboarding_id'); $checkPartnerReferralsResponse = $this->httpClient->request( 'GET', - sprintf('%s/partner-referrals/check/%s', $this->url, (string) $request->query->get('onboarding_id')), + sprintf('%s/partner-referrals/check/%s', $this->url, $onboardingId), [ 'headers' => [ 'Content-Type' => 'application/json', @@ -61,10 +62,15 @@ public function process( 'client_secret' => $response['client_secret'], 'merchant_id' => $response['merchant_id'], 'sylius_merchant_id' => $response['sylius_merchant_id'], - 'onboarding_id' => $request->query->get('onboarding_id'), + 'onboarding_id' => $onboardingId, 'partner_attribution_id' => $response['partner_attribution_id'], ]); + $permissionsGranted = (bool) $request->query->get('permissionsGranted', true); + if (!$permissionsGranted) { + $paymentMethod->setEnabled(false); + } + return $paymentMethod; } diff --git a/src/Resources/config/admin_routing.yml b/src/Resources/config/admin_routing.yml index 2a85c315..2640e666 100644 --- a/src/Resources/config/admin_routing.yml +++ b/src/Resources/config/admin_routing.yml @@ -5,3 +5,9 @@ sylius_paypal_plugin_admin_download_payouts_report: methods: [GET] defaults: _controller: Sylius\PayPalPlugin\Controller\DownloadPayoutsReportAction + +sylius_paypal_plugin_admin_enable_seller: + path: /enable-seller/{id} + methods: [POST] + defaults: + _controller: Sylius\PayPalPlugin\Controller\EnableSellerAction diff --git a/src/Resources/config/config.yaml b/src/Resources/config/config.yaml index f8df9f79..462256c3 100644 --- a/src/Resources/config/config.yaml +++ b/src/Resources/config/config.yaml @@ -30,10 +30,13 @@ sylius_grid: action: download_report: "@SyliusPayPalPlugin/Grid/downloadReport.html.twig" enable_pay_pal: "@SyliusPayPalPlugin/Grid/enablePayPal.html.twig" + enable_seller: "@SyliusPayPalPlugin/Grid/enableSeller.html.twig" grids: sylius_admin_payment_method: actions: item: + enable_seller: + type: enable_seller download_report: type: download_report label: sylius.pay_pal.report diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index 026a6e49..c10406f0 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -14,6 +14,10 @@ + + + + @@ -162,5 +166,14 @@ > + + + + %sylius.paypal.facilitator_url% + + diff --git a/src/Resources/config/services/controller.xml b/src/Resources/config/services/controller.xml index fa4f3afc..47457c91 100644 --- a/src/Resources/config/services/controller.xml +++ b/src/Resources/config/services/controller.xml @@ -50,6 +50,11 @@ + + + + + diff --git a/src/Resources/translations/flashes.en.yml b/src/Resources/translations/flashes.en.yml index 4dd37338..ff39ea0e 100644 --- a/src/Resources/translations/flashes.en.yml +++ b/src/Resources/translations/flashes.en.yml @@ -2,4 +2,6 @@ sylius: pay_pal: order_cancelled: 'PayPal order has been cancelled' payment_cancelled: 'PayPal payment has been cancelled' + payment_enabled: 'PayPal payment has just been enabled.' + payment_not_enabled: 'PayPal payment could not be enabled. Try again later.' something_went_wrong: 'Something went wrong. Please, try again.' diff --git a/src/Resources/views/Grid/enableSeller.html.twig b/src/Resources/views/Grid/enableSeller.html.twig new file mode 100644 index 00000000..34efc619 --- /dev/null +++ b/src/Resources/views/Grid/enableSeller.html.twig @@ -0,0 +1,5 @@ +{% if data.gatewayConfig.factoryName == 'sylius.pay_pal' and not data.enabled %} +
+ +
+{% endif %}