/**
  * Return a response instance from response data.
  */
 public static function fromData($data, $httpCode = null)
 {
     // An error or error collection.
     if ($httpCode >= Http::BAD_REQUEST || Helper::dataGet($data, 'errors')) {
         // 4xx and 5xx errors.
         // Return an error collection.
         return Response\ErrorCollection::fromData($data, $httpCode);
     }
     // Session key.
     if (Helper::dataGet($data, 'merchantSessionKey') && Helper::dataGet($data, 'expiry')) {
         return Response\SessionKey::fromData($data, $httpCode);
     }
     // A card identifier.
     if (Helper::dataGet($data, 'cardIdentifier') || Helper::dataGet($data, 'card-identifier')) {
         return Response\CardIdentifier::fromData($data, $httpCode);
     }
     // A payment.
     if (Helper::dataGet($data, 'transactionId') && Helper::dataGet($data, 'transactionType') == AbstractRequest::TRANSACTION_TYPE_PAYMENT) {
         return Response\Payment::fromData($data, $httpCode);
     }
     // A repeat payment.
     if (Helper::dataGet($data, 'transactionId') && Helper::dataGet($data, 'transactionType') == AbstractRequest::TRANSACTION_TYPE_REPEAT) {
         return Response\Repeat::fromData($data, $httpCode);
     }
     // A refund payment.
     if (Helper::dataGet($data, 'transactionId') && Helper::dataGet($data, 'transactionType') == AbstractRequest::TRANSACTION_TYPE_REFUND) {
         return Response\Refund::fromData($data, $httpCode);
     }
     // 3D Secure response.
     // This is the simplest of all the messages - just a status and nothing else.
     // Make sure there is no transactionType field.
     $secure3dStatusList = Response\Secure3D::constantList('STATUS3D');
     $status = Helper::dataGet($data, 'status');
     if ($status && in_array($status, $secure3dStatusList) && !Helper::dataGet($data, 'transactionId')) {
         return Response\Secure3D::fromData($data, $httpCode);
     }
     // A 3D Secure redirect.
     // Like Secure3D, this one does not have a TransactionType, though shares many fields
     // with the abstract transaction response.
     if (Helper::dataGet($data, 'statusCode') == '2007' && Helper::dataGet($data, 'status') == AbstractTransaction::STATUS_3DAUTH) {
         return Response\Secure3DRedirect::fromData($data, $httpCode);
     }
     // A void instruction.
     if (Helper::dataGet($data, 'instructionType') == 'void') {
         return Response\Void::fromData($data, $httpCode);
     }
     // A 204 with an empty body is a quiet accpetance that what was send is successful.
     // e.g. returned when a CVV is linked to a card.
     if ($httpCode == 204 && empty($data)) {
         return Response\NoContent::fromData($data, $httpCode);
     }
 }
 protected function set3dSecure($data)
 {
     $secure3D = Helper::dataGet($data, '3DSecure');
     if ($secure3D) {
         // Create a 3DSecure object from the array data.
         $this->secure3D = Secure3D::fromData($secure3D);
     }
 }