src/BackOffice/ConfigurationBundle/Payment/Common/Message/AbstractResponse.php line 267

Open in your IDE?
  1. <?php
  2. namespace App\BackOffice\ConfigurationBundle\Payment\Common\Message;
  3. use Exception;
  4. use App\BackOffice\ConfigurationBundle\Payment\Common\Message\ResponseInterface;
  5. use ArrayAccess;
  6. use JsonSerializable;
  7. class AbstractResponse implements ResponseInterfaceArrayAccessJsonSerializable
  8. {
  9.     /**
  10.      * Gateway response codes
  11.      *
  12.      * Example:
  13.      * "103" => [
  14.      *  'isFatal' => false,
  15.      *  'parsedCode' => ResponseInterface::PARTNER_3DSECURE_REQUIRED,
  16.      *  'description' => '3DS required',
  17.      *  'is_split_billing' => false
  18.      * ],
  19.      *
  20.      * @const array
  21.      */
  22.     protected const codes = [];
  23.     // These error codes will NOT be retried in the automatic retry process
  24.     protected const AUTOMATIC_RETRY_SKIP_CODES = [];
  25.     /**
  26.      * @var string $customerId
  27.      *
  28.      * Customer created in the psp
  29.      */
  30.     protected $customerId;
  31.     /**
  32.      * Generic WR codes
  33.      *  Code => Description
  34.      */
  35.     protected $genericCodes = [
  36.         ResponseInterface::PARTNER_SUCCESSFUL_TRANSACTION =>  ResponseInterface::SUCCESSFUL_DESCRIPTION,
  37.         ResponseInterface::PARTNER_SUCCESSFUL_AUTH => ResponseInterface::PARTNER_SUCCESSFUL_AUTH,
  38.         ResponseInterface::PARTNER_SPLIT_CODE => ResponseInterface::PARTNER_SPLIT_CODE,
  39.         ResponseInterface::PARTNER_UNKNOWN_CODE => ResponseInterface::PARTNER_UNKNOWN_CODE,
  40.         ResponseInterface::PARTNER_REDIRECT_3DS_DECLINE => 'Transaction has been declined by the bank',
  41.         ResponseInterface::PARTNER_REDIRECT_3DS_DECLINE2 => 'Transaction has been declined by the bank',
  42.         ResponseInterface::PARTNER_REDIRECT_3DS_CANCEL => 'Transaction annulĂ©e',
  43.         ResponseInterface::PARTNER_REDIRECT_3DS_ERROR => 'Erreur lors du paiement',
  44.         ResponseInterface::PARTNER_DISABLED_FOR_AUTO => 'Mid disabled for auto processing',
  45.     ];
  46.     /**
  47.      * The data contained in the response.
  48.      *
  49.      * @var mixed
  50.      */
  51.     protected $data;
  52.     /**
  53.      * Shortcut to the response code contained in data
  54.      * @var mixed
  55.      */
  56.     protected $responseCode;
  57.     /**
  58.      * Constructor
  59.      *
  60.      * @param mixed|null $data
  61.      */
  62.     public function __construct($data)
  63.     {
  64.         $this->data $data;
  65.         $this->responseCode is_string($data) ? $data null;
  66.     }
  67.     /**
  68.      * Is the response successful?
  69.      *
  70.      * @return bool
  71.      */
  72.     public function isSuccessful(): bool
  73.     {
  74.         return false;
  75.     }
  76.     /**
  77.      * Is the response pending?
  78.      *
  79.      * @return boolean
  80.      */
  81.     public function isPending(): bool
  82.     {
  83.         return false;
  84.     }
  85.     /**
  86.      * Is it a fatal error (non-retryable)?
  87.      *
  88.      * @throws \InvalidArgumentException
  89.      * @return bool
  90.      */
  91.     public function isFatal(): bool
  92.     {
  93.         $this->checkCodeExists();
  94.         return $this->responseCode && (static::codes[$this->responseCode]['isFatal'] ?? false);
  95.     }
  96.     /**
  97.      * Does the response require a redirect?
  98.      *
  99.      * @return boolean
  100.      */
  101.     public function isRedirect(): bool
  102.     {
  103.         return false;
  104.     }
  105.     /**
  106.      * Gets the redirect target url.
  107.      *
  108.      * @return string|null
  109.      */
  110.     public function getRedirectUrl(): ?string
  111.     {
  112.         return null;
  113.     }
  114.     /**
  115.      * Get the required redirect method (GET or POST).
  116.      *
  117.      * @return string
  118.      */
  119.     public function getRedirectMethod(): string
  120.     {
  121.         return 'GET';
  122.     }
  123.     /**
  124.      * Gets the redirect form data array, if the redirect method is POST.
  125.      *
  126.      * @return array
  127.      */
  128.     public function getRedirectData(): array
  129.     {
  130.         return [];
  131.     }
  132.     /**
  133.      * Get the description associated with the response code
  134.      * @param string|null $code
  135.      * @return string
  136.      */
  137.     public function getCodeDescription($code null): string
  138.     {
  139.         $code $code ?? $this->responseCode;
  140.         return $this->genericCodes[$code] ?? static::codes[$code]['description'] ??
  141.                 ResponseInterface::NO_DESCRIPTION;
  142.     }
  143.     /**
  144.      * Response code
  145.      *
  146.      * @return mixed A response code from the payment gateway
  147.      */
  148.     public function getCode()
  149.     {
  150.         return $this->responseCode;
  151.     }
  152.     /**
  153.      * Gateway Reference
  154.      *
  155.      * @return null|string A reference provided by the gateway to represent this transaction
  156.      */
  157.     public function getTransactionReference()
  158.     {
  159.         return null;
  160.     }
  161.     /**
  162.      * Get the order ID.
  163.      *
  164.      * @return null|string
  165.      */
  166.     public function getOrderId()
  167.     {
  168.         return null;
  169.     }
  170.     /**
  171.      * Get the response data.
  172.      *
  173.      * @return mixed
  174.      */
  175.     public function getData()
  176.     {
  177.         return $this->data;
  178.     }
  179.     /**
  180.      * Get the token/wallet/registrationId
  181.      *
  182.      * @return string
  183.      */
  184.     public function getToken(): string
  185.     {
  186.         return '';
  187.     }
  188.     /**
  189.      * Checks if code exists
  190.      *
  191.      * @param mixed $code
  192.      * @throws \InvalidArgumentException
  193.      */
  194.     protected function checkCodeExists($code null): void
  195.     {
  196.         $code $code ?? $this->responseCode;
  197.         if ($code && !isset($this->genericCodes[$code]) && !isset(static::codes[$code])) {
  198.             throw new \InvalidArgumentException("Given error code ($code) doesnt exist " get_class($this));
  199.         }
  200.     }
  201.     /**
  202.      * Returns response data as array
  203.      *
  204.      * @return array
  205.      */
  206.     public function toArray(): array
  207.     {
  208.         if (is_array($this->data)) {
  209.             return $this->data;
  210.         } elseif (is_object($this->data)) {
  211.             return get_object_vars($this->data);
  212.         }
  213.         return [];
  214.     }
  215.     /**
  216.      * JsonSerializable interface implementation
  217.      *
  218.      * @return array|mixed
  219.      */
  220.     public function jsonSerialize()
  221.     {
  222.         return $this->toArray();
  223.     }
  224.     /**
  225.      * ArrayAccess interface methods
  226.      *
  227.      * These methods are temporary to be compatible with old array access to the response result.
  228.      * This way we can use "$result->isFatal()" but also we can access the data the old way "$result["result"]["id"]"
  229.      * so we don't have to rewrite the full PSP code.
  230.      * They should be removed when not needed anymore when we have new PSP code that uses the response as an object.
  231.      */
  232.     public function offsetExists($offset): bool
  233.     {
  234.         return isset($this->data[$offset]);
  235.     }
  236.     public function offsetGet($offset)
  237.     {
  238.         return $this->data[$offset];
  239.     }
  240.     public function offsetSet($offset$value): void
  241.     {
  242.         $this->data[$offset] = $value;
  243.     }
  244.     public function offsetUnset($offset): void
  245.     {
  246.         unset($this->data[$offset]);
  247.     }
  248.     public function getBinInfo($bin)
  249.     {
  250.         return null;
  251.     }
  252.     public function getCustomerId(): string
  253.     {
  254.         return $this->customerId;
  255.     }
  256.     public function setCustomerId(string $customerId): void
  257.     {
  258.         $this->customerId $customerId;
  259.     }
  260.     public static function getFatalCodeList(): array
  261.     {
  262.         $fatalCodes array_filter(static::codes, function ($value$key) {
  263.             return $value['isFatal'];
  264.         }, ARRAY_FILTER_USE_BOTH);
  265.         return $fatalCodes;
  266.     }
  267.     /**
  268.      * Can we retry automatically if we get this error code?
  269.      *
  270.      * @param mixed $errorCode
  271.      * @return bool
  272.      */
  273.     public static function canBeAutoRetried($errorCode): bool
  274.     {
  275.         return !in_array($errorCode, static::AUTOMATIC_RETRY_SKIP_CODES ?? []);
  276.     }
  277.     /**
  278.      * Get the list of codes that should not be automatically retried
  279.      *
  280.      * @return array
  281.      */
  282.     public function getSkipRetryCodeList(): array
  283.     {
  284.         $codes = static::AUTOMATIC_RETRY_SKIP_CODES ?? [];
  285.         $data = [];
  286.         foreach ($codes as $code) {
  287.             $data[$code] = $this->getCodeDescription($code);
  288.         }
  289.         return $data;
  290.     }
  291.     /**
  292.      * Get HTML to render
  293.      *
  294.      * @return string|null
  295.      */
  296.     public function getRedirectHtml(): ?string
  297.     {
  298.         return null;
  299.     }
  300. }