/** * @param Message\Request $request * @throws ApiException * @throws PaymentException * @throws SigningException * @return Message\Response */ public function processRequest(Message\Request $request) { $response = NULL; try { foreach ($this->onRequest as $callback) { call_user_func($callback, $request); } try { $httpResponse = $this->sendHttpRequest($request); } catch (\Exception $e) { throw new ApiException($e->getMessage(), 0, $e); } switch ($httpResponse->getStatusCode()) { case ApiException::S400_BAD_REQUEST: case ApiException::S403_FORBIDDEN: case ApiException::S404_NOT_FOUND: throw new ApiException('Payment is probably in wrong state or request is broken', $httpResponse->getStatusCode()); case ApiException::S429_TOO_MANY_REQUESTS: throw new ApiException('Too Many Requests', $httpResponse->getStatusCode()); case ApiException::S503_SERVICE_UNAVAILABLE: throw new ApiException('Service is down for maintenance', $httpResponse->getStatusCode()); } $decoded = @json_decode($responseBody = $httpResponse->getBody(), TRUE); if ($decoded === NULL) { throw new ApiException(sprintf('API returned invalid json %s', $responseBody), $httpResponse->getStatusCode()); } if (!isset($decoded['resultCode'])) { throw new ApiException(sprintf('The "resultCode" key is missing in response %s', $responseBody), $httpResponse->getStatusCode()); } $response = new Message\Response($decoded, $request); if ($decoded['resultCode'] === PaymentException::INTERNAL_ERROR) { throw InternalErrorException::fromResponse($decoded, $response); } if (empty($decoded['signature'])) { throw new ApiException(sprintf('The "signature" key is missing or empty in response %s', $responseBody), $httpResponse->getStatusCode()); } $response->verify($this->signature); switch ($decoded['resultCode']) { case PaymentException::MISSING_PARAMETER: throw MissingParameterException::fromResponse($decoded, $response); case PaymentException::INVALID_PARAMETER: throw InvalidParameterException::fromResponse($decoded, $response); case PaymentException::MERCHANT_BLOCKED: throw MerchantBlockedException::fromResponse($decoded, $response); case PaymentException::SESSION_EXPIRED: throw SessionExpiredException::fromResponse($decoded, $response); case PaymentException::PAYMENT_NOT_FOUND: throw PaymentNotFoundException::fromResponse($decoded, $response); case PaymentException::PAYMENT_NOT_IN_VALID_STATE: throw PaymentNotInValidStateException::fromResponse($decoded, $response); } foreach ($this->onResponse as $callback) { call_user_func($callback, $response); } return $response; } catch (Exception $e) { foreach ($this->onError as $callback) { call_user_func($callback, $e, $response); } throw $e; } }