src/Infrastructure/PaymentGateway/IbanXS/Api.php line 167

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Infrastructure\PaymentGateway\IbanXS;
  4. use Http\Message\MessageFactory;
  5. use Payum\Core\Exception\Http\HttpException;
  6. use Payum\Core\Exception\LogicException;
  7. use Payum\Core\HttpClientInterface;
  8. use Payum\Core\Request\Generic;
  9. use App\Domain\Payment\Model\Payment as DomainPayment;
  10. use Doctrine\DBAL\DriverManager;
  11. use Doctrine\DBAL\ParameterType;
  12. use Doctrine\DBAL\Types\Types;
  13. class Api
  14. {
  15.     // production
  16.     // public const AUTH_URL = 'https://cronosauth.bankxs.eu/auth/realms/GatewayRealm/protocol/openid-connect/token';
  17.     // public const API_URL = 'https://cronos.bankxs.eu/api/v1';
  18.     private string $clientId;
  19.     private string $clientSecret;
  20.     private HttpClientInterface $client;
  21.     private MessageFactory $messageFactory;
  22.     public function __construct(array $options, HttpClientInterface $client, MessageFactory $messageFactory, string $ibanxsAuthTokenUrl, string $ibanxsApiBaseUrlV1)
  23.     {
  24.         if (true === empty($options['client_id'])) {
  25.             throw new \InvalidArgumentException('The client_id option must be set.');
  26.         }
  27.         if (true === empty($options['client_secret'])) {
  28.             throw new \InvalidArgumentException('The client_secret option must be set.');
  29.         }
  30.         $this->clientId = $options['client_id'];
  31.         $this->clientSecret = $options['client_secret'];
  32.         $this->client = $client;
  33.         $this->messageFactory = $messageFactory;
  34.         $this->authUrl = $ibanxsAuthTokenUrl;
  35.         $this->apiUrl = $ibanxsApiBaseUrlV1;
  36.     }
  37.     public function createHostedFlow(array $data, $paymentId = null): array
  38.     {
  39.         return $this->doRequest($data, 'hostedflows', $paymentId);
  40.     }
  41.     private function getToken(): string
  42.     {
  43.         $request = $this->messageFactory->createRequest(
  44.             'POST',
  45.             $this->authUrl,
  46.             [
  47.                 'Content-Type' => 'application/x-www-form-urlencoded',
  48.             ],
  49.             http_build_query([
  50.                 'client_id' => $this->clientId,
  51.                 'client_secret' => $this->clientSecret,
  52.                 'grant_type' => 'client_credentials',
  53.             ])
  54.         );
  55.         $response = $this->client->send($request);
  56.         if (false === ($response->getStatusCode() >= 200 && $response->getStatusCode() < 300)) {
  57.             throw HttpException::factory($request, $response);
  58.         }
  59.         $result = json_decode($response->getBody()->getContents(), true);
  60.         if (null === $result) {
  61.             throw new LogicException("Response content is not valid json: \n\n{$response->getBody()->getContents()}");
  62.         }
  63.         return $result['access_token'];
  64.     }
  65.     private function doRequest(array $data, string $path, $paymentId): array
  66.     {
  67.         $token = $this->getToken();
  68.         // Move fields from params to the root level if present
  69.         if (isset($data['params'])) {
  70.             if (!empty($data['params']['countryCode'])) {
  71.                 $data['countryId'] = $data['params']['countryCode'];
  72.                 unset($data['params']['countryCode']);
  73.             }
  74.             if (!empty($data['params']['bankId'])) {
  75.                 $data['bankId'] = $data['params']['bankId'];
  76.                 unset($data['params']['bankId']);
  77.             }
  78.         }
  79.         $request = $this->messageFactory->createRequest(
  80.             'POST',
  81.             $this->apiUrl . $path,
  82.             [
  83.                 'accept' => 'application/json',
  84.                 'Content-Type' => 'application/json',
  85.                 'authorization' => sprintf('Bearer %s', $token),
  86.             ],
  87.             json_encode($data)
  88.         );
  89.         $request = $this->messageFactory->createRequest(
  90.             'POST',
  91.             $this->apiUrl . $path,
  92.             [
  93.                 'accept' => 'application/json',
  94.                 'Content-Type' => 'application/json',
  95.                 'authorization' => sprintf('Bearer %s', $token),
  96.             ],
  97.             json_encode($data)
  98.         );
  99.         $response = $this->client->send($request);
  100.         if (false === ($response->getStatusCode() >= 200 && $response->getStatusCode() < 300)) {
  101.             $statusCode = $response->getStatusCode();
  102.             $logs = [
  103.                 'title' => 'Failed to redirect to PISP',
  104.                 'details' => (string) $response->getBody()
  105.             ];
  106.             try {
  107.                 $logsJson = json_encode(
  108.                     $logs,
  109.                     JSON_THROW_ON_ERROR
  110.                     | JSON_UNESCAPED_UNICODE
  111.                     | JSON_UNESCAPED_SLASHES
  112.                     | JSON_PRESERVE_ZERO_FRACTION
  113.                 );
  114.                 $conn = \Doctrine\DBAL\DriverManager::getConnection([
  115.                     'url' => $_ENV['DATABASE_URL'] ?? 'mysql://user:pass@127.0.0.1:3306/your_db?charset=utf8mb4',
  116.                 ]);
  117.                 $conn->insert(
  118.                     'payment_logs',
  119.                     [
  120.                         'payment_id' => $paymentId,
  121.                         'status_code' => $statusCode,
  122.                         'logs' => $logsJson,
  123.                     ],
  124.                     [
  125.                         'payment_id' => is_numeric($paymentId) ? ParameterType::INTEGER : ParameterType::STRING,
  126.                         'status_code' => ParameterType::INTEGER,
  127.                         'logs' => Types::JSON,
  128.                     ]
  129.                 );
  130.             } catch (\Throwable $e) {
  131.             }
  132.             throw HttpException::factory($request, $response);
  133.         }
  134.         $result = json_decode($response->getBody()->getContents(), true);
  135.         if (null === $result) {
  136.             throw new LogicException("Response content is not valid json: \n\n{$response->getBody()->getContents()}");
  137.         }
  138.         return $result;
  139.     }
  140. }