You are here

class RobokassaPayment in Commerce robokassa 8.2

Provides the Off-site Robokassa payment gateway.

Plugin annotation


@CommercePaymentGateway(
  id = "robokassa_payment",
  label = "Robokassa payment",
  display_label = "Robokassa",
  forms = {
    "offsite-payment" = "Drupal\commerce_robokassa\PluginForm\OffsiteRedirect\PaymentOffsiteForm",
  },
  payment_method_types = {"credit_card"},
  credit_card_types = {
    "amex", "mir", "jcb", "unionpay", "mastercard", "visa",
  },
)

Hierarchy

Expanded class hierarchy of RobokassaPayment

1 file declares its use of RobokassaPayment
RobokassaStatusController.php in src/Controller/RobokassaStatusController.php

File

src/Plugin/Commerce/PaymentGateway/RobokassaPayment.php, line 40

Namespace

Drupal\commerce_robokassa\Plugin\Commerce\PaymentGateway
View source
class RobokassaPayment extends OffsitePaymentGatewayBase implements RobokassaPaymentInterface {

  /**
   * The price rounder.
   *
   * @var \Drupal\commerce_price\RounderInterface
   */
  protected $rounder;

  /**
   * The language manager.
   *
   * @var \Drupal\Core\Language\LanguageManagerInterface
   */
  protected $languageManager;

  /**
   * The http cleint.
   *
   * @var \GuzzleHttp\Client
   */
  protected $httpClient;

  /**
   * A logger instance.
   *
   * @var \Psr\Log\LoggerInterface
   */
  protected $logger;
  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, PaymentTypeManager $payment_type_manager, PaymentMethodTypeManager $payment_method_type_manager, TimeInterface $time, RounderInterface $rounder, LanguageManagerInterface $language_manager, Client $http_client, LoggerInterface $logger) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager, $payment_type_manager, $payment_method_type_manager, $time);
    $this->rounder = $rounder;
    $this->languageManager = $language_manager;
    $this->httpClient = $http_client;
    $this->logger = $logger;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static($configuration, $plugin_id, $plugin_definition, $container
      ->get('entity_type.manager'), $container
      ->get('plugin.manager.commerce_payment_type'), $container
      ->get('plugin.manager.commerce_payment_method_type'), $container
      ->get('datetime.time'), $container
      ->get('commerce_price.rounder'), $container
      ->get('language_manager'), $container
      ->get('http_client'), $container
      ->get('logger.factory')
      ->get('commerce_robokassa'));
  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    return [
      'MrchLogin' => '',
      'pass1' => '',
      'pass2' => '',
      'server_url_live' => 'https://auth.robokassa.ru/Merchant/Index.aspx',
      'server_url_test' => 'https://auth.robokassa.ru/Merchant/Index.aspx',
      'hash_type' => 'md5',
      'show_robokassa_fee_message' => TRUE,
      'allowed_currencies' => [],
      'logging' => '',
    ] + parent::defaultConfiguration();
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildConfigurationForm($form, $form_state);
    $form['MrchLogin'] = [
      '#type' => 'textfield',
      '#title' => $this
        ->t('login'),
      '#description' => t('Your robokassa login'),
      '#default_value' => $this->configuration['MrchLogin'],
      '#required' => TRUE,
    ];
    $form['pass1'] = [
      '#type' => 'textfield',
      '#title' => $this
        ->t('First password'),
      '#description' => t('Password 1'),
      '#default_value' => $this->configuration['pass1'],
      '#required' => TRUE,
    ];
    $form['pass2'] = [
      '#type' => 'textfield',
      '#title' => $this
        ->t('Second password'),
      '#description' => t('Password 2'),
      '#default_value' => $this->configuration['pass2'],
      '#required' => TRUE,
    ];
    $form['server_url_live'] = [
      '#type' => 'textfield',
      '#title' => $this
        ->t('Server URL'),
      '#default_value' => $this->configuration['server_url_live'],
    ];
    $form['server_url_test'] = [
      '#type' => 'textfield',
      '#title' => $this
        ->t('Server Test URL'),
      '#default_value' => $this->configuration['server_url_test'],
    ];
    $form['hash_type'] = [
      '#type' => 'radios',
      '#title' => $this
        ->t('Hash type'),
      '#options' => [
        'md5' => 'md5',
        'ripemd160' => 'ripemd160',
        'sha1' => 'sha1',
        'sha256' => 'sha256',
        'sha384' => 'sha384',
        'sha512' => 'sha512',
      ],
      '#default_value' => $this->configuration['hash_type'],
      '#required' => TRUE,
    ];
    $form['allowed_currencies'] = [
      '#type' => 'checkboxes',
      '#title' => $this
        ->t('Currencies'),
      '#options' => $this
        ->paymentMethodsList(),
      '#default_value' => $this->configuration['allowed_currencies'],
    ];
    $form['show_robokassa_fee_message'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Show robokassa fee message'),
      '#default_value' => $this->configuration['show_robokassa_fee_message'],
    ];
    $form['logging'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Logging'),
      '#default_value' => $this->configuration['logging'],
    ];
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
    parent::submitConfigurationForm($form, $form_state);
    if (!$form_state
      ->getErrors()) {
      $values = $form_state
        ->getValue($form['#parents']);
      $this->configuration['MrchLogin'] = $values['MrchLogin'];
      if (!empty($values['pass1'])) {
        $this->configuration['pass1'] = $values['pass1'];
      }
      if (!empty($values['pass2'])) {
        $this->configuration['pass2'] = $values['pass2'];
      }
      $this->configuration['server_url_live'] = $values['server_url_live'];
      $this->configuration['server_url_test'] = $values['server_url_test'];
      $this->configuration['hash_type'] = $values['hash_type'];
      $this->configuration['show_robokassa_fee_message'] = $values['show_robokassa_fee_message'];
      $this->configuration['allowed_currencies'] = $values['allowed_currencies'];
      $this->configuration['logging'] = $values['logging'];
    }
  }
  function paymentMethodsList() {
    $url = 'https://auth.robokassa.ru/Merchant/WebService/Service.asmx/GetCurrencies';
    $data = [
      'MerchantLogin' => $this->configuration['MrchLogin'],
      'Language' => $this->languageManager
        ->getCurrentLanguage()
        ->getId() == 'ru' ? 'ru' : 'en',
    ];
    $response = $this->httpClient
      ->get($url, [
      'query' => $data,
    ]);
    $xmlstring = $response
      ->getBody()
      ->getContents();
    $xml = simplexml_load_string($xmlstring, "SimpleXMLElement", LIBXML_NOCDATA);
    $json = json_encode($xml);
    $array = json_decode($json, TRUE);
    $ret = [];
    if (!isset($array['Groups'])) {
      return $ret;
    }
    foreach ($array['Groups'] as $groups) {
      foreach ($groups as $group) {
        foreach ($group['Items'] as $item) {
          if (isset($item['@attributes'])) {
            $item = array(
              $item,
            );
          }
          foreach ($item as $currency) {
            $ret[$currency['@attributes']['Label']] = $currency['@attributes']['Name'];
          }
        }
      }
    }
    return $ret;
  }

  /**
   * {@inheritdoc}
   */
  public function onReturn(OrderInterface $order, Request $request) {
    drupal_set_message($this
      ->t('Payment was processed'));
  }

  /**
   * {@inheritdoc}
   */
  public function onNotify(Request $request) {

    /** @var PaymentInterface $payment */
    $payment = $this
      ->doValidatePost($request);
    if (!$payment) {
      return FALSE;
    }
    $payment
      ->setState('completed');
    $payment
      ->save();
  }
  protected function doCancel(PaymentInterface $payment, array $status_response) {
    $payment
      ->setState('authorization_expired');
    $payment
      ->save();
    return TRUE;
  }

  /**
   * Helper to validate robokassa $_POST data.
   *
   * @param \Symfony\Component\HttpFoundation\Request $data
   *   $_POST to be validated.
   * @param bool $is_interaction
   *   Fallback call flag.
   *
   * @return bool|mixed
   *   Transaction according to POST data or due.
   */
  public function doValidatePost(Request $request, $is_interaction = TRUE) {
    $data = $request->request
      ->all();

    // Exit now if the $_POST was empty.
    if (empty($data)) {
      $this->logger
        ->warning('Interaction URL accessed with no POST data submitted.');
      return FALSE;
    }

    // Exit now if any required keys are not exists in $_POST.
    $required_keys = array(
      'OutSum',
      'InvId',
    );
    if ($is_interaction) {
      $required_keys[] = 'SignatureValue';
    }
    $unavailable_required_keys = array_diff_key(array_flip($required_keys), $data);
    if (!empty($unavailable_required_keys)) {
      $this->logger
        ->warning('Missing POST keys. POST data: <pre>!data</pre>', array(
        '!data' => print_r($unavailable_required_keys, TRUE),
      ));
      return FALSE;
    }

    // Exit now if missing Checkout ID.
    if (empty($this->configuration['MrchLogin'])) {
      $info = array(
        '!settings' => print_r($this->configuration, 1),
        '!data' => print_r($data, TRUE),
      );
      $this->logger
        ->warning('Missing merchant ID.  POST data: <pre>!data</pre> <pre>!settings</pre>', $info);
      return FALSE;
    }
    if ($is_interaction) {
      if ($this->configuration) {

        // Robokassa Signature.
        $robo_sign = $data['SignatureValue'];

        // Create own Signature.
        $signature_data = array(
          $data['OutSum'],
          $data['InvId'],
          $this->configuration['pass2'],
        );
        if (isset($data['shp_trx_id'])) {
          $signature_data[] = 'shp_trx_id=' . $data['shp_trx_id'];
        }
        $sign = hash($this->configuration['hash_type'], implode(':', $signature_data));

        // Exit now if missing Signature.
        if (Unicode::strtoupper($robo_sign) != Unicode::strtoupper($sign)) {
          $this->logger
            ->warning('Missing Signature. 1 POST data: !data', array(
            '!data' => print_r($data, TRUE),
          ));
          return FALSE;
        }
      }
    }
    try {

      /** @var \Drupal\commerce_payment\Entity\PaymentInterface $payment */
      $payment = $this->entityTypeManager
        ->getStorage('commerce_payment')
        ->load($data['shp_trx_id']);
    } catch (InvalidPluginDefinitionException $e) {
      $this->logger
        ->warning('Missing transaction id.  POST data: !data', array(
        '!data' => print_r($data, TRUE),
      ));
      return FALSE;
    }
    $amount = new Price($data['OutSum'], $payment
      ->getAmount()
      ->getCurrencyCode());
    if (!$payment instanceof PaymentInterface) {
      $this->logger
        ->warning('Missing transaction id.  POST data: !data', array(
        '!data' => print_r($data, TRUE),
      ));
      return FALSE;
    }
    if (!$payment
      ->getAmount()
      ->equals($amount)) {
      $this->logger
        ->warning('Missing transaction id amount.  POST data: !data', array(
        '!data' => print_r($data, TRUE),
      ));
      return FALSE;
    }
    return $payment;
  }

  /**
   * Sets transaction 'status' and 'message' depending on RBS status.
   *
   * @param object $transaction
   * @param int $remote_status
   */
  public function setLocalState(PaymentInterface $payment, $remote_status) {
    switch ($remote_status) {
      case 'success':
        $payment
          ->setState('completed');
        break;
      case 'fail':
        $payment
          ->setState('authorization_voided');
        break;
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
OffsitePaymentGatewayBase::getNotifyUrl public function Gets the URL to the "notify" page. Overrides OffsitePaymentGatewayInterface::getNotifyUrl
OffsitePaymentGatewayBase::onCancel public function Processes the "cancel" request. Overrides OffsitePaymentGatewayInterface::onCancel
PaymentGatewayBase::$entityId Deprecated protected property The ID of the parent config entity.
PaymentGatewayBase::$entityTypeManager protected property The entity type manager.
PaymentGatewayBase::$minorUnitsConverter protected property The minor units converter.
PaymentGatewayBase::$parentEntity protected property The parent config entity.
PaymentGatewayBase::$paymentMethodTypes protected property The payment method types handled by the gateway.
PaymentGatewayBase::$paymentType protected property The payment type used by the gateway.
PaymentGatewayBase::$time protected property The time.
PaymentGatewayBase::assertPaymentMethod protected function Asserts that the payment method is neither empty nor expired.
PaymentGatewayBase::assertPaymentState protected function Asserts that the payment state matches one of the allowed states.
PaymentGatewayBase::assertRefundAmount protected function Asserts that the refund amount is valid.
PaymentGatewayBase::buildAvsResponseCodeLabel public function Builds a label for the given AVS response code and card type. Overrides PaymentGatewayInterface::buildAvsResponseCodeLabel 2
PaymentGatewayBase::buildPaymentOperations public function Builds the available operations for the given payment. Overrides PaymentGatewayInterface::buildPaymentOperations 1
PaymentGatewayBase::calculateDependencies public function Calculates dependencies for the configured plugin. Overrides DependentPluginInterface::calculateDependencies
PaymentGatewayBase::canCapturePayment public function
PaymentGatewayBase::canRefundPayment public function
PaymentGatewayBase::canVoidPayment public function
PaymentGatewayBase::collectsBillingInformation public function Gets whether the payment gateway collects billing information. Overrides PaymentGatewayInterface::collectsBillingInformation
PaymentGatewayBase::getConfiguration public function Gets this plugin's configuration. Overrides ConfigurableInterface::getConfiguration
PaymentGatewayBase::getCreditCardTypes public function Gets the credit card types handled by the gateway. Overrides PaymentGatewayInterface::getCreditCardTypes
PaymentGatewayBase::getDefaultForms protected function Gets the default payment gateway forms. 1
PaymentGatewayBase::getDefaultPaymentMethodType public function Gets the default payment method type. Overrides PaymentGatewayInterface::getDefaultPaymentMethodType
PaymentGatewayBase::getDisplayLabel public function Gets the payment gateway display label. Overrides PaymentGatewayInterface::getDisplayLabel
PaymentGatewayBase::getJsLibrary public function Gets the JS library ID. Overrides PaymentGatewayInterface::getJsLibrary
PaymentGatewayBase::getLabel public function Gets the payment gateway label. Overrides PaymentGatewayInterface::getLabel
PaymentGatewayBase::getMode public function Gets the mode in which the payment gateway is operating. Overrides PaymentGatewayInterface::getMode
PaymentGatewayBase::getPaymentMethodTypes public function Gets the payment method types handled by the payment gateway. Overrides PaymentGatewayInterface::getPaymentMethodTypes
PaymentGatewayBase::getPaymentType public function Gets the payment type used by the payment gateway. Overrides PaymentGatewayInterface::getPaymentType
PaymentGatewayBase::getRemoteCustomerId protected function Gets the remote customer ID for the given user.
PaymentGatewayBase::getSupportedModes public function Gets the supported modes. Overrides PaymentGatewayInterface::getSupportedModes
PaymentGatewayBase::setConfiguration public function Sets the configuration for this plugin instance. Overrides ConfigurableInterface::setConfiguration
PaymentGatewayBase::setRemoteCustomerId protected function Sets the remote customer ID for the given user.
PaymentGatewayBase::toMinorUnits public function Converts the given amount to its minor units. Overrides PaymentGatewayInterface::toMinorUnits
PaymentGatewayBase::validateConfigurationForm public function Form validation handler. Overrides PluginFormInterface::validateConfigurationForm
PaymentGatewayBase::__sleep public function Overrides DependencySerializationTrait::__sleep
PaymentGatewayBase::__wakeup public function Overrides DependencySerializationTrait::__wakeup
PluginBase::$configuration protected property Configuration information passed into the plugin. 1
PluginBase::$pluginDefinition protected property The plugin implementation definition. 1
PluginBase::$pluginId protected property The plugin_id.
PluginBase::DERIVATIVE_SEPARATOR constant A string which is used to separate base plugin IDs from the derivative ID.
PluginBase::getBaseId public function Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface::getBaseId
PluginBase::getDerivativeId public function Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface::getDerivativeId
PluginBase::getPluginDefinition public function Gets the definition of the plugin implementation. Overrides PluginInspectionInterface::getPluginDefinition 3
PluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
PluginBase::isConfigurable public function Determines if the plugin is configurable.
PluginWithFormsTrait::getFormClass public function
PluginWithFormsTrait::hasFormClass public function
RobokassaPayment::$httpClient protected property The http cleint.
RobokassaPayment::$languageManager protected property The language manager.
RobokassaPayment::$logger protected property A logger instance.
RobokassaPayment::$rounder protected property The price rounder.
RobokassaPayment::buildConfigurationForm public function Form constructor. Overrides PaymentGatewayBase::buildConfigurationForm
RobokassaPayment::create public static function Creates an instance of the plugin. Overrides PaymentGatewayBase::create
RobokassaPayment::defaultConfiguration public function Gets default configuration for this plugin. Overrides PaymentGatewayBase::defaultConfiguration
RobokassaPayment::doCancel protected function
RobokassaPayment::doValidatePost public function Helper to validate robokassa $_POST data.
RobokassaPayment::onNotify public function Processes the notification request. Overrides OffsitePaymentGatewayBase::onNotify
RobokassaPayment::onReturn public function Processes the "return" request. Overrides OffsitePaymentGatewayBase::onReturn
RobokassaPayment::paymentMethodsList function
RobokassaPayment::setLocalState public function Sets transaction 'status' and 'message' depending on RBS status.
RobokassaPayment::submitConfigurationForm public function Form submission handler. Overrides PaymentGatewayBase::submitConfigurationForm
RobokassaPayment::__construct public function Constructs a new PaymentGatewayBase object. Overrides PaymentGatewayBase::__construct
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.