diff --git a/spec/Client/PayPalClientSpec.php b/spec/Client/PayPalClientSpec.php index 0a9f1dfb..3630d963 100644 --- a/spec/Client/PayPalClientSpec.php +++ b/spec/Client/PayPalClientSpec.php @@ -53,14 +53,15 @@ function let( $this->beConstructedWith( $client, - $requestFactory, - $streamFactory, $logger, $uuidProvider, $payPalConfigurationProvider, $channelContext, 'https://test-api.paypal.com/', - 5 + 5, + false, + $requestFactory, + $streamFactory, ); } @@ -140,15 +141,15 @@ function it_logs_all_requests_if_logging_level_is_increased( ): void { $this->beConstructedWith( $client, - $requestFactory, - $streamFactory, $logger, $uuidProvider, $payPalConfigurationProvider, $channelContext, 'https://test-api.paypal.com/', 5, - true + true, + $requestFactory, + $streamFactory, ); $channelContext->getChannel()->willReturn($channel); diff --git a/src/Api/WebhookApi.php b/src/Api/WebhookApi.php index 1004f6de..d13e2b33 100644 --- a/src/Api/WebhookApi.php +++ b/src/Api/WebhookApi.php @@ -4,6 +4,7 @@ namespace Sylius\PayPalPlugin\Api; +use GuzzleHttp\ClientInterface as GuzzleClientInterface; use Psr\Http\Client\ClientInterface; use Psr\Http\Message\RequestFactoryInterface; use Psr\Http\Message\StreamFactoryInterface; @@ -11,15 +12,36 @@ final class WebhookApi implements WebhookApiInterface { public function __construct( - private readonly ClientInterface $client, + private readonly GuzzleClientInterface|ClientInterface $client, private readonly string $baseUrl, - private readonly RequestFactoryInterface $requestFactory, - private readonly StreamFactoryInterface $streamFactory, + private readonly ?RequestFactoryInterface $requestFactory = null, + private readonly ?StreamFactoryInterface $streamFactory = null, ) { + if ($this->client instanceof GuzzleClientInterface) { + trigger_deprecation( + 'sylius/paypal-plugin', + '1.6', + 'Passing GuzzleHttp\ClientInterface as a first argument in the constructor is deprecated and will be removed. Use Psr\Http\Client\ClientInterface instead.', + self::class, + ); + } + + if (null === $this->requestFactory && null === $this->streamFactory) { + trigger_deprecation( + 'sylius/paypal-plugin', + '1.6', + 'Not passing $requestFactory and $streamFactory to %s constructor is deprecated and will be removed', + self::class, + ); + } } public function register(string $token, string $webhookUrl): array { + if ($this->client instanceof GuzzleClientInterface && null === $this->requestFactory && null === $this->streamFactory) { + return $this->legacyRegister($token, $webhookUrl); + } + $request = $this->requestFactory->createRequest('POST', $this->baseUrl . 'v1/notifications/webhooks') ->withHeader('Authorization', 'Bearer ' . $token) ->withHeader('Content-Type', 'application/json') @@ -42,4 +64,23 @@ public function register(string $token, string $webhookUrl): array return (array) json_decode($response->getBody()->getContents(), true); } + + private function legacyRegister(string $token, string $webhookUrl): array + { + $response = $this->client->request('POST', $this->baseUrl . 'v1/notifications/webhooks', [ + 'headers' => [ + 'Authorization' => 'Bearer ' . $token, + 'Content-Type' => 'application/json', + 'Accept' => 'application/json', + ], + 'json' => [ + 'url' => preg_replace('/^http:/i', 'https:', $webhookUrl), + 'event_types' => [ + ['name' => 'PAYMENT.CAPTURE.REFUNDED'], + ], + ], + ]); + + return (array) json_decode($response->getBody()->getContents(), true); + } } diff --git a/src/Client/PayPalClient.php b/src/Client/PayPalClient.php index 7135a449..c5434b0d 100644 --- a/src/Client/PayPalClient.php +++ b/src/Client/PayPalClient.php @@ -13,6 +13,7 @@ namespace Sylius\PayPalPlugin\Client; +use GuzzleHttp\ClientInterface as GuzzleClientInterface; use GuzzleHttp\Exception\ConnectException; use GuzzleHttp\Exception\RequestException; use Psr\Http\Client\ClientInterface; @@ -30,9 +31,7 @@ final class PayPalClient implements PayPalClientInterface { public function __construct( - private readonly ClientInterface $client, - private readonly RequestFactoryInterface $requestFactory, - private readonly StreamFactoryInterface $streamFactory, + private readonly GuzzleClientInterface|ClientInterface $client, private readonly LoggerInterface $logger, private readonly UuidProviderInterface $uuidProvider, private readonly PayPalConfigurationProviderInterface $payPalConfigurationProvider, @@ -40,7 +39,26 @@ public function __construct( private readonly string $baseUrl, private int $requestTrialsLimit, private readonly bool $loggingLevelIncreased = false, + private readonly ?RequestFactoryInterface $requestFactory = null, + private readonly ?StreamFactoryInterface $streamFactory = null, ) { + if ($this->client instanceof GuzzleClientInterface) { + trigger_deprecation( + 'sylius/paypal-plugin', + '1.6', + 'Passing GuzzleHttp\ClientInterface as a first argument in the constructor is deprecated and will be removed. Use Psr\Http\Client\ClientInterface instead.', + self::class, + ); + } + + if (null === $this->requestFactory && null === $this->streamFactory) { + trigger_deprecation( + 'sylius/paypal-plugin', + '1.6', + 'Not passing $requestFactory and $streamFactory to %s constructor is deprecated and will be removed', + self::class, + ); + } } public function authorize(string $clientId, string $clientSecret): array @@ -125,43 +143,49 @@ private function request(string $method, string $url, string $token, array $data private function doRequest(string $method, string $fullUrl, array $options): ResponseInterface { try { - $request = $this->requestFactory->createRequest($method, $fullUrl); - - if (isset($options['auth'])) { - $request = $request->withHeader( - 'Authorization', - sprintf( - 'Basic %s', - base64_encode(sprintf('%s:%s', $options['auth'][0], $options['auth'][1])), - ), - ); - } + if ($this->client instanceof GuzzleClientInterface && null === $this->requestFactory && null === $this->streamFactory) { + $response = $this->client->request($method, $fullUrl, $options); + } else { + $request = $this->requestFactory->createRequest($method, $fullUrl); + + if (isset($options['auth'])) { + $request = $request->withHeader( + 'Authorization', + sprintf( + 'Basic %s', + base64_encode(sprintf('%s:%s', $options['auth'][0], $options['auth'][1])), + ), + ); + } - if (isset($options['form_params'])) { - $request = $request->withHeader('Content-Type', 'application/x-www-form-urlencoded'); - $request = $request->withBody( - $this->streamFactory->createStream(http_build_query( - $options['form_params'], - '', - '&', - \PHP_QUERY_RFC1738, - )), - ); - } + if (isset($options['form_params'])) { + $request = $request->withHeader('Content-Type', 'application/x-www-form-urlencoded'); + $request = $request->withBody( + $this->streamFactory->createStream( + http_build_query( + $options['form_params'], + '', + '&', + \PHP_QUERY_RFC1738, + ), + ), + ); + } - if (isset($options['json'])) { - $request = $request->withBody( - $this->streamFactory->createStream(json_encode($options['json'])), - ); - } + if (isset($options['json'])) { + $request = $request->withBody( + $this->streamFactory->createStream(json_encode($options['json'])), + ); + } - if (isset($options['headers'])) { - foreach ($options['headers'] as $header => $headerValue) { - $request = $request->withHeader($header, $headerValue); + if (isset($options['headers'])) { + foreach ($options['headers'] as $header => $headerValue) { + $request = $request->withHeader($header, $headerValue); + } } - } - $response = $this->client->sendRequest($request); + $response = $this->client->sendRequest($request); + } } catch (ConnectException $exception) { --$this->requestTrialsLimit; if ($this->requestTrialsLimit === 0) { diff --git a/src/Resources/config/services/api.xml b/src/Resources/config/services/api.xml index adadf6bb..5c203c12 100644 --- a/src/Resources/config/services/api.xml +++ b/src/Resources/config/services/api.xml @@ -12,8 +12,6 @@ class="Sylius\PayPalPlugin\Client\PayPalClient" > - - @@ -21,6 +19,8 @@ %sylius.pay_pal.api_base_url% %sylius.pay_pal.request_trials_limit% %sylius.paypal.logging.increased% + +