You are here

class Mollie in Commerce Mollie 8

Same name in this branch
  1. 8 src/Plugin/Commerce/PaymentGateway/Mollie.php \Drupal\commerce_mollie\Plugin\Commerce\PaymentGateway\Mollie
  2. 8 src/Plugin/Commerce/PaymentMethodType/Mollie.php \Drupal\commerce_mollie\Plugin\Commerce\PaymentMethodType\Mollie

Provides the Mollie payment gateway.

Plugin annotation


@CommercePaymentGateway(
  id = "mollie",
  label = "Mollie",
  display_label = "Mollie",
  forms = {
    "offsite-payment" =
  "Drupal\commerce_mollie\PluginForm\OffsiteRedirect\MolliePaymentOffsiteForm",
  },
  payment_method_types = {"mollie"},
  requires_billing_information = FALSE,
)

Hierarchy

Expanded class hierarchy of Mollie

2 string references to 'Mollie'
Mollie::buildLabel in src/Plugin/Commerce/PaymentMethodType/Mollie.php
Builds a label for the given payment method.
MolliePaymentOffsiteFormTest::setUp in tests/src/Functional/MolliePaymentOffsiteFormTest.php

File

src/Plugin/Commerce/PaymentGateway/Mollie.php, line 37

Namespace

Drupal\commerce_mollie\Plugin\Commerce\PaymentGateway
View source
class Mollie extends OffsitePaymentGatewayBase implements HasPaymentInstructionsInterface {

  /**
   * The Mollie gateway used for making API calls.
   *
   * @var \Mollie\Api\MollieApiClient
   */
  protected $api;

  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, PaymentTypeManager $payment_type_manager, PaymentMethodTypeManager $payment_method_type_manager, TimeInterface $time) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager, $payment_type_manager, $payment_method_type_manager, $time);

    // MollieAPIClient should be setup in the payment_method?
    $this->api = Drupal::service('commerce_mollie.mollie.api');

    // Initialize api_key.
    try {
      if (!empty($configuration['api_key_live']) && $configuration['api_key_live'] !== $this
        ->defaultConfiguration()['api_key_live'] && $configuration['mode'] === 'live') {
        $this->api
          ->setApiKey($configuration['api_key_live']);
      }
      elseif (!empty($configuration['api_key_test']) && $configuration['api_key_test'] !== $this
        ->defaultConfiguration()['api_key_test'] && $configuration['mode'] === 'test') {
        $this->api
          ->setApiKey($configuration['api_key_test']);
      }
    } catch (MollieApiException $e) {
      ErrorHelper::handleException($e);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    $default_configuration = [
      'api_key_test' => 'test_',
      'api_key_live' => 'live_',
      'callback_domain' => '',
    ];
    return $default_configuration + parent::defaultConfiguration();
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildConfigurationForm($form, $form_state);

    /*
     * Set a warning message when the default order-type workflow does not have
     * a validation step.
     */

    /** @var \Drupal\commerce_order\Entity\OrderType $order_type */
    $order_workflow = Drupal::config('commerce_order.commerce_order_type.default')
      ->get('workflow');
    if (strpos($order_workflow, 'validation') === FALSE) {
      $link = Link::fromTextAndUrl($this
        ->t('Configure Order Types workflow'), Url::fromRoute('entity.commerce_order_type.collection'))
        ->toString();
      Drupal::messenger()
        ->addWarning($this
        ->t('It is recommended to configure a workflow with a Validation step. @link', [
        '@link' => $link,
      ]));
    }

    // Build the form.
    $host = Drupal::request()
      ->getHost();
    $form['api_key_test'] = [
      '#type' => 'textfield',
      '#title' => $this
        ->t('Mollie Test API-key'),
      '#default_value' => $this->configuration['api_key_test'],
      '#required' => TRUE,
    ];
    $form['api_key_live'] = [
      '#type' => 'textfield',
      '#title' => $this
        ->t('Mollie Live API-key'),
      '#default_value' => $this->configuration['api_key_live'],
      '#required' => TRUE,
    ];
    $form['callback_domain'] = [
      '#type' => 'textfield',
      '#title' => $this
        ->t('Callback domain'),
      '#description' => $this
        ->t('Callback domain that Mollie must use to post transaction results to.<br/>
      <ul>
        <li>Do not add an "/" after .com</li>
        <li>You must include https:// or http://</li>
        <li>The domain must be reachable for the Mollie servers, otherwise payments are not processed.</li>
      </ul>
      For live websites this is the your live domain</br><br/>

      If left empty the domain visible in the browser window will be used.<br/>
      Currently that is: @host<br/><br/>

      While developing you can use a tunneled domain that hits your local development machine.<br/>
      This can be done with https://localtunnel.github.io/www<br/>
      <code>lt --port 80 --local-host @host</code>
      ', [
        '@host' => $host,
      ]),
      '#default_value' => $this->configuration['callback_domain'],
      '#required' => FALSE,
    ];
    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['api_key_test'] = $values['api_key_test'];
      $this->configuration['api_key_live'] = $values['api_key_live'];
      $this->configuration['callback_domain'] = $values['callback_domain'];
    }
  }

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

    /*
     * Handle status that Mollie returns.
     */
    $mollie_payment_remote_id = $request
      ->get('id');
    if (empty($mollie_payment_remote_id)) {
      $data = json_decode($request
        ->getContent(), TRUE);
      $request->request
        ->replace(is_array($data) ? $data : []);
      $mollie_payment_remote_id = $request->request
        ->get('id');
    }

    /** @var \Drupal\commerce_payment\PaymentStorage $payment_storage */
    $payment_storage = $this->entityTypeManager
      ->getStorage('commerce_payment');

    /** @var \Drupal\commerce_payment\Entity\Payment $payment */
    $payment = $payment_storage
      ->loadByRemoteId($mollie_payment_remote_id);

    // Only proceed if payment is created.
    if ($payment === NULL) {
      return new JsonResponse();
    }

    // Evaluate the remote status.

    /** @var \Mollie\Api\Resources\Payment $mollie_payment_remote_object */
    $mollie_payment_remote_object = $this
      ->getApi()->payments
      ->get($mollie_payment_remote_id);

    // Commerce payment and order state.
    switch ($mollie_payment_remote_object->status) {
      case MolliePaymentStatus::STATUS_PAID:

        // Capture payment.
        $payment_transition = $payment
          ->getState()
          ->getWorkflow()
          ->getTransition('authorize_capture');
        $payment
          ->getState()
          ->applyTransition($payment_transition);
        break;
      case MolliePaymentStatus::STATUS_CANCELED:

        // Cancel payment.
        $payment_transition = $payment
          ->getState()
          ->getWorkflow()
          ->getTransition('void');
        $payment
          ->getState()
          ->applyTransition($payment_transition);
        break;
      case MolliePaymentStatus::STATUS_OPEN:

        // Authorize payment.
        $payment_transition = $payment
          ->getState()
          ->getWorkflow()
          ->getTransition('authorize');
        $payment
          ->getState()
          ->applyTransition($payment_transition);
        break;
      case MolliePaymentStatus::STATUS_FAILED:

        // Void payment.
        $payment_transition = $payment
          ->getState()
          ->getWorkflow()
          ->getTransition('void');
        $payment
          ->getState()
          ->applyTransition($payment_transition);
        break;
      case MolliePaymentStatus::STATUS_EXPIRED:

        // Expire payment.
        $payment_transition = $payment
          ->getState()
          ->getWorkflow()
          ->getTransition('expire');
        $payment
          ->getState()
          ->applyTransition($payment_transition);
        break;
    }
    $payment
      ->setRemoteState($mollie_payment_remote_object->status);
    $payment
      ->save();

    // Return empty response with 200 status code.
    return new JsonResponse();
  }

  /**
   * Return initalized Mollie API.
   */
  public function getApi() {
    return $this->api;
  }

  /**
   * {@inheritdoc}
   */
  public function createRemotePayment(PaymentInterface $payment, $data) {

    // Prepare data for remote payment creation.
    $transaction_data = [
      'amount' => [
        'currency' => $payment
          ->getAmount()
          ->getCurrencyCode(),
        'value' => number_format($payment
          ->getAmount()
          ->getNumber(), 2, '.', ''),
      ],
      'description' => $this
        ->t('@store order @order_id', [
        '@store' => $payment
          ->getOrder()
          ->getStore()
          ->label(),
        '@order_id' => $payment
          ->getOrderId(),
      ]),
      'redirectUrl' => $data['return'],
      'webhookUrl' => $this
        ->getNotifyUrl()
        ->toString(),
      'metadata' => [
        'order_id' => $payment
          ->getOrderId(),
      ],
    ];

    // Create remote payment and save remote data in the drupal payment.
    try {
      $mollie_payment = $this
        ->getApi()->payments
        ->create($transaction_data);
      $payment
        ->setRemoteId($mollie_payment->id);
      $payment
        ->setRemoteState($mollie_payment->status);
      $payment
        ->save();
      ErrorHelper::handleErrors($mollie_payment);
    } catch (MollieApiException $e) {
      ErrorHelper::handleException($e);
    }
    return $mollie_payment;
  }

  /**
   * {@inheritdoc}
   */
  public function getNotifyUrl() {
    return Url::fromRoute('commerce_payment.notify', [
      'commerce_payment_gateway' => $this->entityId,
    ], [
      'absolute' => TRUE,
      'base_url' => $this->configuration['callback_domain'],
    ]);
  }

  /**
   * Builds the payment instructions.
   *
   * @param \Drupal\commerce_payment\Entity\PaymentInterface $payment
   *   The payment.
   *
   * @return array
   *   A render array containing the payment instructions.
   */
  public function buildPaymentInstructions(PaymentInterface $payment = NULL) {
    $instructions = [
      '#type' => 'processed_text',
      '#text' => $this
        ->t('Thank you for your payment with @gateway. We will inform you when your payment is processed. This is usually done within 24 hours.', [
        '@gateway' => $this
          ->getDisplayLabel(),
      ], [
        'context' => 'Mollie payment instructions',
      ]),
      '#format' => 'plain_text',
    ];
    return $instructions;
  }

}

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.
Mollie::$api protected property The Mollie gateway used for making API calls.
Mollie::buildConfigurationForm public function Form constructor. Overrides PaymentGatewayBase::buildConfigurationForm
Mollie::buildPaymentInstructions public function Builds the payment instructions. Overrides HasPaymentInstructionsInterface::buildPaymentInstructions
Mollie::createRemotePayment public function
Mollie::defaultConfiguration public function Gets default configuration for this plugin. Overrides PaymentGatewayBase::defaultConfiguration
Mollie::getApi public function Return initalized Mollie API.
Mollie::getNotifyUrl public function Gets the URL to the "notify" page. Overrides OffsitePaymentGatewayBase::getNotifyUrl
Mollie::onNotify public function Processes the notification request. Overrides OffsitePaymentGatewayBase::onNotify
Mollie::submitConfigurationForm public function Form submission handler. Overrides PaymentGatewayBase::submitConfigurationForm
Mollie::__construct public function Constructs a new PaymentGatewayBase object. Overrides PaymentGatewayBase::__construct
OffsitePaymentGatewayBase::onCancel public function Processes the "cancel" request. Overrides OffsitePaymentGatewayInterface::onCancel
OffsitePaymentGatewayBase::onReturn public function Processes the "return" request. Overrides OffsitePaymentGatewayInterface::onReturn 1
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::create public static function Creates an instance of the plugin. Overrides ContainerFactoryPluginInterface::create 2
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
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.