Skip to content

Commit

Permalink
Improve Saferpay client error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
Zales0123 committed Jul 29, 2024
1 parent 4f5f09f commit b73f93d
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 23 deletions.
59 changes: 58 additions & 1 deletion spec/Client/SaferpayClientSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@
use CommerceWeavers\SyliusSaferpayPlugin\Resolver\SaferpayApiBaseUrlResolverInterface;
use Payum\Core\Security\TokenInterface;
use PhpSpec\ObjectBehavior;
use Psr\Log\LoggerInterface;
use Sylius\Bundle\PayumBundle\Model\GatewayConfigInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Model\PaymentInterface;
use Sylius\Component\Core\Model\PaymentMethodInterface;
use Symfony\Component\HttpClient\Exception\TimeoutException;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;

Expand All @@ -29,8 +32,15 @@ function let(
SaferpayClientBodyFactoryInterface $saferpayClientBodyFactory,
SaferpayApiBaseUrlResolverInterface $saferpayApiBaseUrlResolver,
PaymentEventDispatcherInterface $paymentEventDispatcher,
LoggerInterface $logger,
): void {
$this->beConstructedWith($client, $saferpayClientBodyFactory, $saferpayApiBaseUrlResolver, $paymentEventDispatcher);
$this->beConstructedWith(
$client,
$saferpayClientBodyFactory,
$saferpayApiBaseUrlResolver,
$paymentEventDispatcher,
$logger,
);
}

function it_implements_saferpay_client_interface(): void
Expand Down Expand Up @@ -862,6 +872,53 @@ function it_performs_get_terminal_request(
]);
}

function it_logs_exceptions_if_something_fails(
LoggerInterface $logger,
HttpClientInterface $client,
SaferpayClientBodyFactoryInterface $saferpayClientBodyFactory,
SaferpayApiBaseUrlResolverInterface $saferpayApiBaseUrlResolver,
GatewayConfigInterface $gatewayConfig,
): void {
$saferpayClientBodyFactory->provideHeadersForTerminal()->willReturn([
'Saferpay-ApiVersion' => '1.33',
'Saferpay-RequestId' => 'b27de121-ffa0-4f1d-b7aa-b48109a88486',
]);
$saferpayApiBaseUrlResolver->resolve($gatewayConfig)->willReturn('https://test.saferpay.com/api/');

$gatewayConfig->getConfig()->willReturn([
'username' => 'USERNAME',
'password' => 'PASSWORD',
'customer_id' => 'CUSTOMER_ID',
'terminal_id' => 'TERMINAL_ID',
'sandbox' => true,
]);

$client
->request(
'GET',
'https://test.saferpay.com/api/rest/customers/CUSTOMER_ID/terminals/TERMINAL_ID',
[
'headers' => [
'Authorization' => 'Basic ' . base64_encode('USERNAME:PASSWORD'),
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'Saferpay-ApiVersion' => '1.33',
'Saferpay-RequestId' => 'b27de121-ffa0-4f1d-b7aa-b48109a88486',
],
'body' => json_encode([]),
]
)
->willThrow(new TimeoutException('Timeout'))
;

$logger->error('Timeout')->shouldBeCalled();

$this
->getTerminal($gatewayConfig)
->shouldReturn(['error' => 'Timeout', 'StatusCode' => Response::HTTP_INTERNAL_SERVER_ERROR])
;
}

private function getExampleAuthorizeResponse(): string
{
return <<<RESPONSE
Expand Down
35 changes: 13 additions & 22 deletions src/Client/SaferpayClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use Psr\Log\LoggerInterface;
use Sylius\Component\Core\Model\PaymentInterface;
use Sylius\Component\Core\Model\PaymentMethodInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
Expand Down Expand Up @@ -265,30 +266,20 @@ private function request(
GatewayConfigInterface $gatewayConfig,
array $headers = [],
): array {
$reqUrl = $this->provideFullUrl($gatewayConfig, $url);
$reqHeaders = array_merge($this->provideHeaders($gatewayConfig), $headers);
$reqBbody = json_encode($body);
$fullUrl = $this->provideFullUrl($gatewayConfig, $url);
$requestHeaders = array_merge($this->provideHeaders($gatewayConfig), $headers);
$requestBody = json_encode($body);

try {
try {
$response = $this->client->request($method, $reqUrl, [
'headers' => $reqHeaders,
'body' => $reqBbody,
]);
$headers = $response->getHeaders(false);
} catch (TimeoutExceptionInterface $e) {
// retry once
$this->logger->error($e->getMessage());
$response = $this->client->request($method, $reqUrl, [
'headers' => $reqHeaders,
'body' => $reqBbody,
]);
$headers = $response->getHeaders(false);
}
} catch (TimeoutExceptionInterface|TransportExceptionInterface|ServerExceptionInterface $e) {
$this->logger->error($e->getMessage());

return ['error' => $e->getMessage(), 'StatusCode' => 500];
$response = $this->client->request($method, $fullUrl, [
'headers' => $requestHeaders,
'body' => $requestBody,
]);
$headers = $response->getHeaders(false);
} catch (TimeoutExceptionInterface|TransportExceptionInterface|ServerExceptionInterface $exception) {
$this->logger->error($exception->getMessage());

return ['error' => $exception->getMessage(), 'StatusCode' => Response::HTTP_INTERNAL_SERVER_ERROR];
}

if (str_starts_with($headers['content-type'][0], 'application/json')) {
Expand Down

0 comments on commit b73f93d

Please sign in to comment.