commit 11734edf322d9b230c57d8e6b0eef23f5783703b
Author: Bart Feenstra <bart@mynameisbart.com>
Date:   Tue Apr 22 16:30:40 2014 +0200

    foo

diff --git a/payment/lib/Drupal/payment/Entity/Payment.php b/payment/lib/Drupal/payment/Entity/Payment.php
index 74ccabf..453a121 100644
--- a/payment/lib/Drupal/payment/Entity/Payment.php
+++ b/payment/lib/Drupal/payment/Entity/Payment.php
@@ -12,6 +12,8 @@ use Drupal\Core\Entity\ContentEntityBase;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Field\FieldDefinition;
+use Drupal\payment\Event\PaymentEvents;
+use Drupal\payment\Event\PaymentStatusSet;
 use Drupal\payment\Payment as PaymentServiceWrapper;
 use Drupal\payment\Plugin\Payment\LineItem\PaymentLineItemInterface;
 use Drupal\payment\Plugin\Payment\Method\PaymentMethodInterface as PluginPaymentMethodInterface;
@@ -214,16 +216,21 @@ class Payment extends ContentEntityBase implements PaymentInterface {
    * {@inheritdoc}
    */
   public function setStatus(PluginPaymentStatusInterface $status, $notify = TRUE) {
-    $previousStatus = $this->getStatus();
+    $previous_status = $this->getStatus();
     $status->setPaymentId($this->id());
     // Prevent duplicate statuses.
     if (!$this->getStatus() || $this->getStatus()->getPluginId() != $status->getPluginId()) {
       $this->statuses[] = $status;
     }
     if ($notify) {
-      $handler = \Drupal::moduleHandler();
-      foreach ($handler->getImplementations('payment_status_set') as $moduleName) {
-        $handler->invoke($moduleName, 'payment_status_set', array($this, $previousStatus));
+      /** @var \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher */
+      $event_dispatcher = \Drupal::service('event_dispatcher');
+      $event = new PaymentStatusSet($this, $previous_status);
+      $event_dispatcher->dispatch(PaymentEvents::PAYMENT_STATUS_SET, $event);
+
+      $module_handler = \Drupal::moduleHandler();
+      foreach ($module_handler->getImplementations('payment_status_set') as $moduleName) {
+        $module_handler->invoke($moduleName, 'payment_status_set', array($this, $previous_status));
         // If a hook invocation has added another log item, a new loop with
         // invocations has already been executed and we don't need to continue
         // with this one.
diff --git a/payment/lib/Drupal/payment/Event/PaymentEvents.php b/payment/lib/Drupal/payment/Event/PaymentEvents.php
new file mode 100644
index 0000000..3c62bee
--- /dev/null
+++ b/payment/lib/Drupal/payment/Event/PaymentEvents.php
@@ -0,0 +1,57 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\payment\Event\PaymentEvents.
+ */
+
+namespace Drupal\payment\Event;
+
+/**
+ * Defines Payment events.
+ */
+final class PaymentEvents {
+
+  /**
+   * The name of the event that is fired when payment execution access is
+   * checked.
+   *
+   * @see hook_payment_execute_access()
+   * @see \Drupal\payment\Event\PaymentExecuteAccess
+   */
+  const PAYMENT_EXECUTE_ACCESS = 'drupal.payment.payment_execute_access';
+
+  /**
+   * The name of the event that is fired before a payment is executed.
+   *
+   * @see hook_payment_pre_execute()
+   * @see \Drupal\payment\Event\PaymentPreExecute
+   */
+  const PAYMENT_PRE_EXECUTE = 'drupal.payment.payment_pre_execute';
+
+  /**
+   * The name of the event that is fired after a new payment status is set.
+   *
+   * @see hook_payment_status_set()
+   * @see \Drupal\payment\Event\PaymentStatusSet
+   */
+  const PAYMENT_STATUS_SET = 'drupal.payment.payment_status_set';
+
+  /**
+   * The name of the event that is fired before the payment type's original
+   * context is resumed.
+   *
+   * @see hook_payment_type_pre_resume_context()
+   * @see \Drupal\payment\Event\PaymentTypePreResumeContext
+   */
+  const PAYMENT_TYPE_PRE_RESUME_CONTEXT = 'drupal.payment.payment_type_pre_resume_context';
+
+  /**
+   * The name of the event that alters
+   * \Drupal\payment\QueueInterface::loadPaymentIds() results.
+   *
+   * @see hook_payment_queue_payment_ids_alter()
+   * @see \Drupal\payment\Event\PaymentQueuePaymentIdsAlter
+   */
+  const PAYMENT_QUEUE_PAYMENT_IDS_ALTER = 'drupal.payment.payment_queue_payment_ids_alter';
+}
diff --git a/payment/lib/Drupal/payment/Event/PaymentExecuteAccess.php b/payment/lib/Drupal/payment/Event/PaymentExecuteAccess.php
new file mode 100644
index 0000000..cc0d6d3
--- /dev/null
+++ b/payment/lib/Drupal/payment/Event/PaymentExecuteAccess.php
@@ -0,0 +1,122 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\payment\Event\PaymentExecuteAccess.
+ */
+
+namespace Drupal\payment\Event;
+
+use Drupal\Core\Access\AccessInterface;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\payment\Entity\PaymentInterface;
+use Drupal\payment\Plugin\Payment\Method\PaymentMethodInterface;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Provides an event that is dispatched when access is checked for payment
+ * execution.
+ *
+ * @see \Drupal\payment\Event\PaymentEvents::PAYMENT_EXECUTE_ACCESS
+ */
+class PaymentExecuteAccess extends Event implements AccessInterface {
+
+  /**
+   * The access check results.
+   *
+   * @var string[]
+   *   An array with self::ALLOW, self::DENY, or self::KILL.
+   */
+  protected $accessResults = array();
+
+  /**
+   * The account to check access for.
+   *
+   * @var \Drupal\payment\Entity\PaymentInterface
+   */
+  protected $account;
+
+  /**
+   * The payment.
+   *
+   * @var \Drupal\payment\Entity\PaymentInterface
+   */
+  protected $payment;
+
+  /**
+   * The payment method.
+   *
+   * @var \Drupal\payment\Plugin\Payment\Method\PaymentMethodInterface
+   */
+  protected $paymentMethod;
+
+  /**-
+   * Constructs a new class instance.
+   *
+   * @param \Drupal\payment\Entity\PaymentInterface $payment
+   *   The payment for which the context will be resumed
+   * @param \Drupal\payment\Plugin\Payment\Method\PaymentMethodInterface $payment_method
+   *
+   * @param \Drupal\Core\Session\AccountInterface
+   */
+  public function __construct(PaymentInterface $payment, PaymentMethodInterface $payment_method, AccountInterface $account) {
+    $this->payment = $payment;
+    $this->paymentMethod = $payment_method;
+    $this->account = $account;
+  }
+
+  /**
+   * Gets the payment for which execution access is checked.
+   *
+   * @return \Drupal\payment\Entity\PaymentInterface
+   *   $payment->getPaymentMethod() contains the method currently configured,
+   *   but NOT the method that $payment should be tested against, which is
+   *   $payment_method.
+   */
+  public function getPayment() {
+    return $this->payment;
+  }
+
+  /**
+   * Gets the payment method that should execute the payment.
+   *
+   * @return \Drupal\payment\Plugin\Payment\Method\PaymentMethodInterface
+   */
+  public function getPaymentMethod() {
+    return $this->paymentMethod;
+  }
+
+  /**
+   * Gets the account for which to check access.
+   *
+   * @return \Drupal\Core\Session\AccountInterface
+   */
+  public function getAccount() {
+    return $this->account;
+  }
+
+  /**
+   * Gets the access check results.
+   *
+   * @return string[]
+   *   An array with self::ALLOW, self::DENY, or self::KILL.
+   */
+  public function getAccessResults() {
+    return $this->accessResults;
+  }
+
+  /**
+   * Sets an access check result.
+   *
+   * @param string
+   *   self::ALLOW, self::DENY, or self::KILL.
+   *
+   * @return $this
+   */
+  public function setAccessResult($access_result) {
+    $this->accessResults[] = $access_result;
+
+    return $this;
+  }
+
+}
diff --git a/payment/lib/Drupal/payment/Event/PaymentPreExecute.php b/payment/lib/Drupal/payment/Event/PaymentPreExecute.php
new file mode 100644
index 0000000..85cb315
--- /dev/null
+++ b/payment/lib/Drupal/payment/Event/PaymentPreExecute.php
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\payment\Event\PaymentPreExecute.
+ */
+
+namespace Drupal\payment\Event;
+
+use Drupal\payment\Entity\PaymentInterface;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Provides an event that is dispatched before a payment is executed.
+ *
+ * @see \Drupal\payment\Event\PaymentEvents::PAYMENT_PRE_EXECUTE
+ */
+class PaymentPreExecute extends Event {
+
+  /**
+   * The payment.
+   *
+   * @var \Drupal\payment\Entity\PaymentInterface
+   */
+  protected $payment;
+
+  /**-
+   * Constructs a new class instance.
+   *
+   * @param \Drupal\payment\Entity\PaymentInterface $payment
+   *   The payment that will be executed.
+   *
+   * @param \Drupal\Core\Session\AccountInterface
+   */
+  public function __construct(PaymentInterface $payment) {
+    $this->payment = $payment;
+  }
+
+  /**
+   * Gets the payment that will be executed
+   *
+   * @return \Drupal\payment\Entity\PaymentInterface
+   */
+  public function getPayment() {
+    return $this->payment;
+  }
+
+}
diff --git a/payment/lib/Drupal/payment/Event/PaymentQueuePaymentIdsAlter.php b/payment/lib/Drupal/payment/Event/PaymentQueuePaymentIdsAlter.php
new file mode 100644
index 0000000..614b940
--- /dev/null
+++ b/payment/lib/Drupal/payment/Event/PaymentQueuePaymentIdsAlter.php
@@ -0,0 +1,98 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\payment\Event\PaymentQueuePaymentIdsAlter.
+ */
+
+namespace Drupal\payment\Event;
+
+use Drupal\Core\Access\AccessInterface;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Provides an event that alters
+ * \Drupal\payment\QueueInterface::loadPaymentIds() results.
+ *
+ * @see \Drupal\payment\Event\PaymentEvents::PAYMENT_QUEUE_PAYMENT_IDS_ALTER
+ */
+class PaymentQueuePaymentIdsAlter extends Event implements AccessInterface {
+
+  /**
+   * The queue category ID.
+   *
+   * @var string
+   */
+  protected $categoryId;
+
+  /**
+   * The ID of the user that must own the payments.
+   *
+   * @var int
+   */
+  protected $ownerId;
+
+  /**
+   * The IDs of available payments as loaded by the queue.
+   *
+   * @var int[]
+   */
+  protected $paymentIds;
+
+  /**-
+   * Constructs a new class instance.
+   *
+   * @param string $category_id
+   *   The queue category ID.
+   * @param int $owner_id
+   *   The ID of the user that must own the paymnets.
+   * @param int[] $payment_ids
+   *   The IDs of available payments as loaded by the queue.
+   */
+  public function __construct($category_id, $owner_id, array &$payment_ids) {
+    $this->categoryId = $category_id;
+    $this->ownerId = $owner_id;
+    $this->paymentIds = $payment_ids;
+  }
+
+  /**
+   * Gets the queue category ID.
+   *
+   * @return string
+   */
+  public function getCategoryId() {
+    return $this->categoryId;
+  }
+
+  /**
+   * Gets the ID of the user who owns the payments.
+   *
+   * @return int
+   */
+  public function getOwnerId() {
+    return $this->ownerId;
+  }
+
+  /**
+   * Gets the IDs of the available payments.
+   *
+   * @return int[]
+   */
+  public function getPaymentIds() {
+    return $this->paymentIds;
+  }
+
+  /**
+   * Sets the IDs of the available payments.
+   *
+   * @param int[] $payment_ids
+   *
+   * @return $this
+   */
+  public function setPaymentIds(array $payment_ids) {
+    $this->paymentIds = $payment_ids;
+
+    return $this;
+  }
+
+}
diff --git a/payment/lib/Drupal/payment/Event/PaymentStatusSet.php b/payment/lib/Drupal/payment/Event/PaymentStatusSet.php
new file mode 100644
index 0000000..caff3c7
--- /dev/null
+++ b/payment/lib/Drupal/payment/Event/PaymentStatusSet.php
@@ -0,0 +1,67 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\payment\Event\PaymentStatusSet.
+ */
+
+namespace Drupal\payment\Event;
+
+use Drupal\payment\Entity\PaymentInterface;
+use Drupal\payment\plugin\payment\status\PaymentStatusInterface;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Provides an event that is dispatched after a new status is set on a payment.
+ *
+ * @see \Drupal\payment\Event\PaymentEvents::PAYMENT_STATUS_SET
+ */
+class PaymentStatusSet extends Event {
+
+  /**
+   * The payment.
+   *
+   * @var \Drupal\payment\Entity\PaymentInterface
+   */
+  protected $payment;
+
+  /**
+   * The previous payment status.
+   *
+   * @var \Drupal\payment\Plugin\Payment\Status\PaymentStatusInterface|null
+   */
+  protected $previousPaymentStatus;
+
+  /**-
+   * Constructs a new class instance.
+   *
+   * @param \Drupal\payment\Entity\PaymentInterface $payment
+   *   The payment the status was set on.
+   * @param \Drupal\payment\Plugin\Payment\Status\PaymentStatusInterface $previous_payment_status|null
+   *   The payment's previous status.
+   */
+  public function __construct(PaymentInterface $payment, PaymentStatusInterface $previous_payment_status = NULL) {
+    $this->payment = $payment;
+    $this->previousPaymentStatus = $previous_payment_status;
+  }
+
+  /**
+   * Gets the payment the status was set on.
+   *
+   * @return \Drupal\payment\Entity\PaymentInterface
+   */
+  public function getPayment() {
+    return $this->payment;
+  }
+
+  /**
+   * Gets the payment's previous status.
+   *
+   * @return \Drupal\payment\Plugin\Payment\Status\PaymentStatusInterface|null
+   *   The previous status, or NULL of there is none.
+   */
+  public function getPreviousPaymentStatus() {
+    return $this->previousPaymentStatus;
+  }
+
+}
diff --git a/payment/lib/Drupal/payment/Event/PaymentTypePreResumeContext.php b/payment/lib/Drupal/payment/Event/PaymentTypePreResumeContext.php
new file mode 100644
index 0000000..1ba3e61
--- /dev/null
+++ b/payment/lib/Drupal/payment/Event/PaymentTypePreResumeContext.php
@@ -0,0 +1,47 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\payment\Event\PaymentTypePreResumeContext.
+ */
+
+namespace Drupal\payment\Event;
+
+use Drupal\payment\Entity\PaymentInterface;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Provides an event that is dispatched before the payment type's original
+ * context is resumed.
+ *
+ * @see \Drupal\payment\Event\PaymentEvents::PAYMENT_TYPE_PRE_RESUME_CONTEXT
+ */
+class PaymentTypePreResumeContext extends Event {
+
+  /**
+   * The payment.
+   *
+   * @var \Drupal\payment\Entity\PaymentInterface
+   */
+  protected $payment;
+
+  /**-
+   * Constructs a new class instance.
+   *
+   * @param \Drupal\payment\Entity\PaymentInterface $payment
+   *   The payment for which the context will be resumed
+   */
+  public function __construct(PaymentInterface $payment) {
+    $this->payment = $payment;
+  }
+
+  /**
+   * Gets the payment for which the context will be resumed.
+   *
+   * @return \Drupal\payment\Entity\PaymentInterface
+   */
+  public function getPayment() {
+    return $this->payment;
+  }
+
+}
diff --git a/payment/lib/Drupal/payment/Plugin/Payment/Method/Basic.php b/payment/lib/Drupal/payment/Plugin/Payment/Method/Basic.php
index 8b758ad..7a68508 100644
--- a/payment/lib/Drupal/payment/Plugin/Payment/Method/Basic.php
+++ b/payment/lib/Drupal/payment/Plugin/Payment/Method/Basic.php
@@ -12,6 +12,7 @@ use Drupal\Core\Utility\Token;
 use Drupal\payment\Entity\PaymentInterface;
 use Drupal\payment\Plugin\Payment\Status\PaymentStatusManagerInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 
 /**
  * A basic payment method that does not transfer money.
@@ -46,14 +47,16 @@ class Basic extends PaymentMethodBase implements ContainerFactoryPluginInterface
    *   The plugin implementation definition.
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
    *   The module handler.
+   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
+   *   The event dispatcher.
    * @param \Drupal\Core\Utility\Token $token
    *   The token API.
    * @param \Drupal\payment\Plugin\Payment\Status\PaymentStatusManagerInterface
    *   The payment status manager.
    */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ModuleHandlerInterface $module_handler, Token $token, PaymentStatusManagerInterface $payment_status_manager) {
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ModuleHandlerInterface $module_handler, EventDispatcherInterface $event_dispatcher, Token $token, PaymentStatusManagerInterface $payment_status_manager) {
     $configuration += $this->defaultConfiguration();
-    parent::__construct($configuration, $plugin_id, $plugin_definition, $module_handler, $token);
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $module_handler, $event_dispatcher, $token);
     $this->paymentStatusManager = $payment_status_manager;
   }
 
@@ -61,7 +64,7 @@ class Basic extends PaymentMethodBase implements ContainerFactoryPluginInterface
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static($configuration, $plugin_id, $plugin_definition, $container->get('module_handler'), $container->get('token'), $container->get('plugin.manager.payment.status'));
+    return new static($configuration, $plugin_id, $plugin_definition, $container->get('module_handler'), $container->get('event_dispatcher'), $container->get('token'), $container->get('plugin.manager.payment.status'));
   }
 
   /**
diff --git a/payment/lib/Drupal/payment/Plugin/Payment/Method/PaymentMethodBase.php b/payment/lib/Drupal/payment/Plugin/Payment/Method/PaymentMethodBase.php
index ea6a16e..5f0e4b0 100644
--- a/payment/lib/Drupal/payment/Plugin/Payment/Method/PaymentMethodBase.php
+++ b/payment/lib/Drupal/payment/Plugin/Payment/Method/PaymentMethodBase.php
@@ -13,7 +13,11 @@ use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Utility\Token;
 use Drupal\payment\Entity\PaymentInterface;
+use Drupal\payment\Event\PaymentEvents;
+use Drupal\payment\Event\PaymentExecuteAccess;
+use Drupal\payment\Event\PaymentPreExecute;
 use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 
 /**
  * A base payment method plugin.
@@ -27,6 +31,13 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
 abstract class PaymentMethodBase extends PluginBase implements AccessInterface, ContainerFactoryPluginInterface, PaymentMethodInterface {
 
   /**
+   * The event dispatcher.
+   *
+   * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
+   */
+  protected $eventDispatcher;
+
+  /**
    * The module handler.
    *
    * @var \Drupal\Core\Extension\ModuleHandlerInterface
@@ -58,12 +69,15 @@ abstract class PaymentMethodBase extends PluginBase implements AccessInterface,
    *   The plugin implementation definition.
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
    *   The module handler.
+   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
+   *   The event dispatcher.
    * @param \Drupal\Core\Utility\Token $token
    *   The token API.
    */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ModuleHandlerInterface $module_handler, Token $token) {
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ModuleHandlerInterface $module_handler, EventDispatcherInterface $event_dispatcher, Token $token) {
     $configuration += $this->defaultConfiguration();
     parent::__construct($configuration, $plugin_id, $plugin_definition);
+    $this->eventDispatcher = $event_dispatcher;
     $this->moduleHandler = $module_handler;
     $this->token = $token;
   }
@@ -72,7 +86,7 @@ abstract class PaymentMethodBase extends PluginBase implements AccessInterface,
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static($configuration, $plugin_id, $plugin_definition, $container->get('module_handler'), $container->get('token'));
+    return new static($configuration, $plugin_id, $plugin_definition, $container->get('module_handler'), $container->get('event_dispatcher'), $container->get('token'));
   }
 
   /**
@@ -209,10 +223,14 @@ abstract class PaymentMethodBase extends PluginBase implements AccessInterface,
    * @return bool
    */
   protected function paymentExecuteAccessEvent(PaymentInterface $payment, AccountInterface $account) {
-    $access = $this->moduleHandler->invokeAll('payment_execute_access', array($payment, $this, $account));
+    $event = new PaymentExecuteAccess($payment, $this, $account);
+    $this->eventDispatcher->dispatch(PaymentEvents::PAYMENT_EXECUTE_ACCESS, $event);
+
+    $hook_access_results = $this->moduleHandler->invokeAll('payment_execute_access', array($payment, $this, $account));
 
+    $access_results = array_merge($event->getAccessResults(), $hook_access_results);
     // If there are no results, grant access.
-    return empty($access) || in_array(self::ALLOW, $access, TRUE) && !in_array(self::KILL, $access, TRUE);
+    return empty($access_results) || in_array(self::ALLOW, $access_results, TRUE) && !in_array(self::KILL, $access_results, TRUE);
   }
 
   /**
@@ -223,6 +241,8 @@ abstract class PaymentMethodBase extends PluginBase implements AccessInterface,
    * @return bool
    */
   protected function paymentExecuteEvent(PaymentInterface $payment) {
+    $event = new PaymentPreExecute($payment);
+    $this->eventDispatcher->dispatch(PaymentEvents::PAYMENT_PRE_EXECUTE, $event);
     $this->moduleHandler->invokeAll('payment_pre_execute', array($payment));
     // @todo invoke Rules event.
   }
diff --git a/payment/lib/Drupal/payment/Plugin/Payment/Type/PaymentTypeBase.php b/payment/lib/Drupal/payment/Plugin/Payment/Type/PaymentTypeBase.php
index 1030a97..2640f32 100644
--- a/payment/lib/Drupal/payment/Plugin/Payment/Type/PaymentTypeBase.php
+++ b/payment/lib/Drupal/payment/Plugin/Payment/Type/PaymentTypeBase.php
@@ -6,11 +6,14 @@
 
 namespace Drupal\payment\Plugin\Payment\Type;
 
-use Drupal\Component\Plugin\PluginBase;
+use Drupal\Core\Plugin\PluginBase;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\payment\Entity\PaymentInterface;
+use Drupal\payment\Event\PaymentEvents;
+use Drupal\payment\Event\PaymentTypePreResumeContext;
 use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 
 /**
  * Defines base payment type.
@@ -18,6 +21,13 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
 abstract class PaymentTypeBase extends PluginBase implements ContainerFactoryPluginInterface, PaymentTypeInterface {
 
   /**
+   * The event dispatcher.
+   *
+   * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
+   */
+  protected $eventDispatcher;
+
+  /**
    * The module handler.
    *
    * @var \Drupal\Core\Extension\ModuleHandlerInterface
@@ -42,10 +52,13 @@ abstract class PaymentTypeBase extends PluginBase implements ContainerFactoryPlu
    *   The plugin implementation definition.
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
    *   The module handler.
+   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
+   *   The event dispatcher.
    */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ModuleHandlerInterface $module_handler) {
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ModuleHandlerInterface $module_handler, EventDispatcherInterface $event_dispatcher) {
     $configuration += $this->defaultConfiguration();
     parent::__construct($configuration, $plugin_id, $plugin_definition);
+    $this->eventDispatcher = $event_dispatcher;
     $this->moduleHandler = $module_handler;
   }
 
@@ -53,7 +66,7 @@ abstract class PaymentTypeBase extends PluginBase implements ContainerFactoryPlu
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static($configuration, $plugin_id, $plugin_definition, $container->get('module_handler'));
+    return new static($configuration, $plugin_id, $plugin_definition, $container->get('module_handler'), $container->get('event_dispatcher'));
   }
 
   /**
@@ -100,6 +113,8 @@ abstract class PaymentTypeBase extends PluginBase implements ContainerFactoryPlu
    * the context workflow.
    */
   function resumeContext() {
+    $event = new PaymentTypePreResumeContext($this->getPayment());
+    $this->eventDispatcher->dispatch(PaymentEvents::PAYMENT_TYPE_PRE_RESUME_CONTEXT, $event);
     $this->moduleHandler->invokeAll('payment_type_pre_resume_context', array($this->getPayment()));
     // @todo Invoke Rules event.
   }
diff --git a/payment/lib/Drupal/payment/Plugin/Payment/Type/Unavailable.php b/payment/lib/Drupal/payment/Plugin/Payment/Type/Unavailable.php
index 83b7905..f289482 100644
--- a/payment/lib/Drupal/payment/Plugin/Payment/Type/Unavailable.php
+++ b/payment/lib/Drupal/payment/Plugin/Payment/Type/Unavailable.php
@@ -9,6 +9,7 @@ namespace Drupal\payment\Plugin\Payment\Type;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\StringTranslation\TranslationManager;
 use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
 
 /**
@@ -39,11 +40,13 @@ class Unavailable extends PaymentTypeBase {
    *   The plugin implementation definition.
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
    *   The module handler.
+   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
+   *   The event dispatcher.
    * @param \Drupal\Core\StringTranslation\TranslationManager $translation_manager
    *   The translation manager.
    */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ModuleHandlerInterface $module_handler, TranslationManager $translation_manager) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition, $module_handler);
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ModuleHandlerInterface $module_handler, EventDispatcherInterface $event_dispatcher, TranslationManager $translation_manager) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $module_handler, $event_dispatcher);
     $this->translationManager = $translation_manager;
   }
 
@@ -51,7 +54,7 @@ class Unavailable extends PaymentTypeBase {
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static($configuration, $plugin_id, $plugin_definition, $container->get('module_handler'), $container->get('string_translation'));
+    return new static($configuration, $plugin_id, $plugin_definition, $container->get('module_handler'), $container->get('event_dispatcher'), $container->get('string_translation'));
   }
 
   /**
diff --git a/payment/lib/Drupal/payment/Queue.php b/payment/lib/Drupal/payment/Queue.php
index dee3eb7..2f772a5 100644
--- a/payment/lib/Drupal/payment/Queue.php
+++ b/payment/lib/Drupal/payment/Queue.php
@@ -11,7 +11,10 @@ use Drupal\Component\Utility\Random;
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Database\Database;
 use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\payment\Event\PaymentEvents;
+use Drupal\payment\Event\PaymentQueuePaymentIdsAlter;
 use Drupal\payment\Plugin\Payment\Status\PaymentStatusManagerInterface;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 
 /**
  * The payment queue.
@@ -26,6 +29,13 @@ class Queue implements QueueInterface {
   protected $database;
 
   /**
+   * The event dispatcher.
+   *
+   * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
+   */
+  protected $eventDispatcher;
+
+  /**
    * The time it takes for a claim to expire.
    *
    * @var int
@@ -70,11 +80,14 @@ class Queue implements QueueInterface {
    *   A database connection.
    * @param \Drupal\Core\Extension\ModuleHandlerInterface
    *   The module handler.
+   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
+   *   The event dispatcher.
    * @param \Drupal\payment\Plugin\Payment\Status\PaymentStatusManagerInterface
    *   The payment status plugin manager.
    */
-  public function __construct($queue_id, Connection $database, ModuleHandlerInterface $module_handler, PaymentStatusManagerInterface $payment_status_manager) {
+  public function __construct($queue_id, Connection $database, ModuleHandlerInterface $module_handler, EventDispatcherInterface $event_dispatcher, PaymentStatusManagerInterface $payment_status_manager) {
     $this->database = $database;
+    $this->eventDispatcher = $event_dispatcher;
     $this->moduleHandler = $module_handler;
     $this->paymentStatusManager = $payment_status_manager;
     $this->randomGenerator = new Random();
@@ -179,6 +192,23 @@ class Queue implements QueueInterface {
       ->condition('pr.queue_id', $this->queueId);
 
     $payment_ids = $query->execute()->fetchCol();
+
+    return $this->alterLoadedPaymentIds($category_id, $owner_id, $payment_ids);
+  }
+
+  /**
+   * Alters loaded payment IDs.
+   *
+   * @param string $category_id
+   * @param int $owner_id
+   * @param int[] $payment_ids
+   *
+   * @return int[] $payment_ids
+   */
+  protected function alterLoadedPaymentIds($category_id, $owner_id, array $payment_ids) {
+    $event = new PaymentQueuePaymentIdsAlter($category_id, $owner_id, $payment_ids);
+    $this->eventDispatcher->dispatch(PaymentEvents::PAYMENT_QUEUE_PAYMENT_IDS_ALTER, $event);
+    $payment_ids = $event->getPaymentIds();
     $this->moduleHandler->alter('payment_queue_payment_ids', $category_id, $owner_id, $payment_ids);
     // @todo Add a Rules event.
 
diff --git a/payment/lib/Drupal/payment/Tests/Event/PaymentEventsUnitTest.php b/payment/lib/Drupal/payment/Tests/Event/PaymentEventsUnitTest.php
new file mode 100644
index 0000000..5c337a9
--- /dev/null
+++ b/payment/lib/Drupal/payment/Tests/Event/PaymentEventsUnitTest.php
@@ -0,0 +1,39 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\payment\Event\PaymentEventsUnitTest.
+ */
+
+namespace Drupal\payment\Tests\Event;
+
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\payment\Event\PaymentEvents
+ */
+class PaymentEventsUnitTest extends UnitTestCase {
+
+  /**
+   * {@inheritdoc}
+   */
+  static function getInfo() {
+    return array(
+      'description' => '',
+      'group' => 'Payment',
+      'name' => '\Drupal\payment\Event\PaymentEvents unit test',
+    );
+  }
+
+  /**
+   * Tests constants with event names.
+   */
+  public function testEventNames() {
+    $class = new \ReflectionClass('\Drupal\payment\Event\PaymentEvents');
+    foreach ($class->getConstants() as $event_name) {
+      // Make sure that every event name is properly namespaced.
+      $this->assertSame(0, strpos($event_name, 'drupal.payment.'));
+    }
+  }
+
+}
diff --git a/payment/lib/Drupal/payment/Tests/Event/PaymentExecuteAccessUnitTest.php b/payment/lib/Drupal/payment/Tests/Event/PaymentExecuteAccessUnitTest.php
new file mode 100644
index 0000000..1d34ec7
--- /dev/null
+++ b/payment/lib/Drupal/payment/Tests/Event/PaymentExecuteAccessUnitTest.php
@@ -0,0 +1,105 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\payment\Event\PaymentExecuteAccessUnitTest.
+ */
+
+namespace Drupal\payment\Tests\Event;
+
+use Drupal\payment\Event\PaymentExecuteAccess;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\payment\Event\PaymentExecuteAccess
+ */
+class PaymentExecuteAccessUnitTest extends UnitTestCase {
+
+  /**
+   * The account to check access for.
+   *
+   * @var \Drupal\payment\Entity\PaymentInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $account;
+
+  /**
+   * The event under test.
+   *
+   * @var \Drupal\payment\Event\PaymentExecuteAccess
+   */
+  protected $event;
+
+  /**
+   * The payment.
+   *
+   * @var \Drupal\payment\Entity\PaymentInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $payment;
+
+  /**
+   * The payment method.
+   *
+   * @var \Drupal\payment\Plugin\Payment\Method\PaymentMethodInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $paymentMethod;
+
+  /**
+   * {@inheritdoc}
+   */
+  static function getInfo() {
+    return array(
+      'description' => '',
+      'group' => 'Payment',
+      'name' => '\Drupal\payment\Event\PaymentExecuteAccess unit test',
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   *
+   * @covers ::__construct
+   */
+  public function setUp() {
+    $this->account = $this->getMock('\Drupal\Core\Session\AccountInterface');
+
+    $this->payment = $this->getMockBuilder('\Drupal\payment\Entity\Payment')
+      ->disableOriginalConstructor()
+      ->getMock();
+
+    $this->paymentMethod = $this->getMock('\Drupal\payment\Plugin\Payment\Method\PaymentMethodInterface');
+
+    $this->event = new PaymentExecuteAccess($this->payment, $this->paymentMethod, $this->account);
+  }
+
+  /**
+   * @covers ::getAccount
+   */
+  public function testGetAccount() {
+    $this->assertSame($this->account, $this->event->getAccount());
+  }
+
+  /**
+   * @covers ::getPayment
+   */
+  public function testGetPayment() {
+    $this->assertSame($this->payment, $this->event->getPayment());
+  }
+
+  /**
+   * @covers ::getPaymentMethod
+   */
+  public function testGetPaymentMethod() {
+    $this->assertSame($this->paymentMethod, $this->event->getPaymentMethod());
+  }
+
+  /**
+   * @covers ::getAccessResults
+   * @covers ::setAccessResult
+   */
+  public function testGetAccessResults() {
+    $result = $this->randomName();
+    $this->assertSame($this->event, $this->event->setAccessResult($result));
+    $this->assertSame(array($result), $this->event->getAccessResults());
+  }
+
+}
diff --git a/payment/lib/Drupal/payment/Tests/Event/PaymentPreExecuteUnitTest.php b/payment/lib/Drupal/payment/Tests/Event/PaymentPreExecuteUnitTest.php
new file mode 100644
index 0000000..4e08176
--- /dev/null
+++ b/payment/lib/Drupal/payment/Tests/Event/PaymentPreExecuteUnitTest.php
@@ -0,0 +1,63 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\payment\Event\PaymentPreExecuteUnitTest.
+ */
+
+namespace Drupal\payment\Tests\Event;
+
+use Drupal\payment\Event\PaymentPreExecute;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\payment\Event\PaymentPreExecute
+ */
+class PaymentPreExecuteUnitTest extends UnitTestCase {
+
+  /**
+   * The event under test.
+   *
+   * @var \Drupal\payment\Event\PaymentPreExecute
+   */
+  protected $event;
+
+  /**
+   * The payment.
+   *
+   * @var \Drupal\payment\Entity\PaymentInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $payment;
+
+  /**
+   * {@inheritdoc}
+   */
+  static function getInfo() {
+    return array(
+      'description' => '',
+      'group' => 'Payment',
+      'name' => '\Drupal\payment\Event\PaymentPreExecute unit test',
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   *
+   * @covers ::__construct
+   */
+  public function setUp() {
+    $this->payment = $this->getMockBuilder('\Drupal\payment\Entity\Payment')
+      ->disableOriginalConstructor()
+      ->getMock();
+
+    $this->event = new PaymentPreExecute($this->payment);
+  }
+
+  /**
+   * @covers ::getPayment
+   */
+  public function testGetPayment() {
+    $this->assertSame($this->payment, $this->event->getPayment());
+  }
+
+}
diff --git a/payment/lib/Drupal/payment/Tests/Event/PaymentQueuePaymentIdsAlterUnitTest.php b/payment/lib/Drupal/payment/Tests/Event/PaymentQueuePaymentIdsAlterUnitTest.php
new file mode 100644
index 0000000..cce31d9
--- /dev/null
+++ b/payment/lib/Drupal/payment/Tests/Event/PaymentQueuePaymentIdsAlterUnitTest.php
@@ -0,0 +1,98 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\payment\Event\PaymentQueuePaymentIdsAlterUnitTest.
+ */
+
+namespace Drupal\payment\Tests\Event;
+
+use Drupal\payment\Event\PaymentQueuePaymentIdsAlter;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\payment\Event\PaymentQueuePaymentIdsAlter
+ */
+class PaymentQueuePaymentIdsAlterUnitTest extends UnitTestCase {
+
+  /**
+   * The queue category ID.
+   *
+   * @var string
+   */
+  protected $categoryId;
+
+  /**
+   * The event under test.
+   *
+   * @var \Drupal\payment\Event\PaymentQueuePaymentIdsAlter
+   */
+  protected $event;
+
+  /**
+   * The ID of the user that must own the payments.
+   *
+   * @var int
+   */
+  protected $ownerId;
+
+  /**
+   * The IDs of available payments as loaded by the queue.
+   *
+   * @var int[]
+   */
+  protected $paymentIds;
+
+  /**
+   * {@inheritdoc}
+   */
+  static function getInfo() {
+    return array(
+      'description' => '',
+      'group' => 'Payment',
+      'name' => '\Drupal\payment\Event\PaymentQueuePaymentIdsAlter unit test',
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   *
+   * @covers ::__construct
+   */
+  public function setUp() {
+    $this->categoryId = $this->randomName();
+
+    $this->ownerId = $this->randomName();
+
+    $this->paymentIds = array($this->randomName());
+
+    $this->event = new PaymentQueuePaymentIdsAlter($this->categoryId, $this->ownerId, $this->paymentIds);
+  }
+
+  /**
+   * @covers ::getCategoryId
+   */
+  public function testGetCategoryId() {
+    $this->assertSame($this->categoryId, $this->event->getCategoryId());
+  }
+
+  /**
+   * @covers ::getOwnerId
+   */
+  public function testGetOwnerId() {
+    $this->assertSame($this->ownerId, $this->event->getOwnerId());
+  }
+
+  /**
+   * @covers ::getPaymentIds
+   * @covers ::setPaymentIds
+   */
+  public function testGetPaymentIds() {
+    $this->assertSame($this->paymentIds, $this->event->getPaymentIds());
+    $payment_ids = array($this->randomName());
+    $this->assertSame($this->event, $this->event->setPaymentIds($payment_ids));
+    $this->assertSame($payment_ids, $this->event->getPaymentIds());
+
+  }
+
+}
diff --git a/payment/lib/Drupal/payment/Tests/Event/PaymentStatusSetUnitTest.php b/payment/lib/Drupal/payment/Tests/Event/PaymentStatusSetUnitTest.php
new file mode 100644
index 0000000..17c38ae
--- /dev/null
+++ b/payment/lib/Drupal/payment/Tests/Event/PaymentStatusSetUnitTest.php
@@ -0,0 +1,79 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\payment\Event\PaymentStatusSetUnitTest.
+ */
+
+namespace Drupal\payment\Tests\Event;
+
+use Drupal\payment\Event\PaymentStatusSet;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\payment\Event\PaymentStatusSet
+ */
+class PaymentStatusSetUnitTest extends UnitTestCase {
+
+  /**
+   * The event under test.
+   *
+   * @var \Drupal\payment\Event\PaymentStatusSet
+   */
+  protected $event;
+
+  /**
+   * The payment.
+   *
+   * @var \Drupal\payment\Entity\PaymentInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $payment;
+
+  /**
+   * The previous payment status.
+   *
+   * @var \Drupal\payment\Plugin\Payment\Status\PaymentStatusInterface|null
+   */
+  protected $previousPaymentStatus;
+
+  /**
+   * {@inheritdoc}
+   */
+  static function getInfo() {
+    return array(
+      'description' => '',
+      'group' => 'Payment',
+      'name' => '\Drupal\payment\Event\PaymentStatusSet unit test',
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   *
+   * @covers ::__construct
+   */
+  public function setUp() {
+    $this->payment = $this->getMockBuilder('\Drupal\payment\Entity\Payment')
+      ->disableOriginalConstructor()
+      ->getMock();
+
+    $this->getMock('\Drupal\payment\Plugin\Payment\Status\PaymentStatusInterface');
+
+    $this->event = new PaymentStatusSet($this->payment, $this->previousPaymentStatus);
+  }
+
+  /**
+   * @covers ::getPayment
+   */
+  public function testGetPayment() {
+    $this->assertSame($this->payment, $this->event->getPayment());
+  }
+
+  /**
+   * @covers ::getPreviousPaymentStatus
+   */
+  public function testGetPreviousPaymentStatus() {
+    $this->assertSame($this->previousPaymentStatus, $this->event->getPreviousPaymentStatus());
+  }
+
+}
diff --git a/payment/lib/Drupal/payment/Tests/Event/PaymentTypePreResumeContextUnitTest.php b/payment/lib/Drupal/payment/Tests/Event/PaymentTypePreResumeContextUnitTest.php
new file mode 100644
index 0000000..8cd0b53
--- /dev/null
+++ b/payment/lib/Drupal/payment/Tests/Event/PaymentTypePreResumeContextUnitTest.php
@@ -0,0 +1,63 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\payment\Event\PaymentTypePreResumeContextUnitTest.
+ */
+
+namespace Drupal\payment\Tests\Event;
+
+use Drupal\payment\Event\PaymentTypePreResumeContext;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\payment\Event\PaymentTypePreResumeContext
+ */
+class PaymentTypePreResumeContextUnitTest extends UnitTestCase {
+
+  /**
+   * The event under test.
+   *
+   * @var \Drupal\payment\Event\PaymentTypePreResumeContext
+   */
+  protected $event;
+
+  /**
+   * The payment.
+   *
+   * @var \Drupal\payment\Entity\PaymentInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $payment;
+
+  /**
+   * {@inheritdoc}
+   */
+  static function getInfo() {
+    return array(
+      'description' => '',
+      'group' => 'Payment',
+      'name' => '\Drupal\payment\Event\PaymentTypePreResumeContext unit test',
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   *
+   * @covers ::__construct
+   */
+  public function setUp() {
+    $this->payment = $this->getMockBuilder('\Drupal\payment\Entity\Payment')
+      ->disableOriginalConstructor()
+      ->getMock();
+
+    $this->event = new PaymentTypePreResumeContext($this->payment);
+  }
+
+  /**
+   * @covers ::getPayment
+   */
+  public function testGetPayment() {
+    $this->assertSame($this->payment, $this->event->getPayment());
+  }
+
+}
diff --git a/payment/lib/Drupal/payment/Tests/Plugin/Payment/Method/BasicUnitTest.php b/payment/lib/Drupal/payment/Tests/Plugin/Payment/Method/BasicUnitTest.php
index cc749d9..05994fd 100644
--- a/payment/lib/Drupal/payment/Tests/Plugin/Payment/Method/BasicUnitTest.php
+++ b/payment/lib/Drupal/payment/Tests/Plugin/Payment/Method/BasicUnitTest.php
@@ -15,6 +15,13 @@ use Drupal\Tests\UnitTestCase;
 class BasicUnitTest extends UnitTestCase {
 
   /**
+   * The event dispatcher.
+   *
+   * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $eventDispatcher;
+
+  /**
    * The module handler used for testing.
    *
    * @var \Drupal\Core\Extension\ModuleHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
@@ -68,6 +75,8 @@ class BasicUnitTest extends UnitTestCase {
   public function setUp() {
     parent::setUp();
 
+    $this->eventDispatcher = $this->getMock('\Symfony\Component\EventDispatcher\EventDispatcherInterface');
+
     $this->moduleHandler = $this->getMock('\Drupal\Core\Extension\ModuleHandlerInterface');
 
     $this->token = $this->getMockBuilder('\Drupal\Core\Utility\Token')
@@ -77,7 +86,7 @@ class BasicUnitTest extends UnitTestCase {
     $this->paymentStatusManager = $this->getMock('\Drupal\payment\Plugin\Payment\Status\PaymentStatusManagerInterface');
 
     $this->plugin = $this->getMockBuilder('\Drupal\payment\Plugin\Payment\Method\Basic')
-      ->setConstructorArgs(array(array(), '', $this->pluginDefinition, $this->moduleHandler, $this->token, $this->paymentStatusManager))
+      ->setConstructorArgs(array(array(), '', $this->pluginDefinition, $this->moduleHandler, $this->eventDispatcher, $this->token, $this->paymentStatusManager))
       ->setMethods(array('t'))
       ->getMock();
     $this->plugin->expects($this->any())
@@ -106,7 +115,7 @@ class BasicUnitTest extends UnitTestCase {
     $payment_status_plugin_id = $this->randomName();
     /** @var \Drupal\payment\Plugin\Payment\Method\Basic|\PHPUnit_Framework_MockObject_MockObject $payment_method_plugin */
     $payment_method_plugin = $this->getMockBuilder('\Drupal\payment\Plugin\Payment\Method\Basic')
-      ->setConstructorArgs(array(array(), '', array(), $this->moduleHandler, $this->token, $this->paymentStatusManager))
+      ->setConstructorArgs(array(array(), '', array(), $this->moduleHandler, $this->eventDispatcher, $this->token, $this->paymentStatusManager))
       ->setMethods(array('executePaymentAccess', 'getStatus'))
       ->getMock();
     $payment_method_plugin->expects($this->once())
diff --git a/payment/lib/Drupal/payment/Tests/Plugin/Payment/Method/PaymentMethodBaseUnitTest.php b/payment/lib/Drupal/payment/Tests/Plugin/Payment/Method/PaymentMethodBaseUnitTest.php
index 483f9cd..95ba807 100644
--- a/payment/lib/Drupal/payment/Tests/Plugin/Payment/Method/PaymentMethodBaseUnitTest.php
+++ b/payment/lib/Drupal/payment/Tests/Plugin/Payment/Method/PaymentMethodBaseUnitTest.php
@@ -8,6 +8,7 @@
 namespace Drupal\payment\Tests\Plugin\Payment\Method;
 
 use Drupal\Core\Access\AccessInterface;
+use Drupal\payment\Event\PaymentEvents;
 use Drupal\Tests\UnitTestCase;
 
 /**
@@ -16,6 +17,13 @@ use Drupal\Tests\UnitTestCase;
 class PaymentMethodBaseUnitTest extends UnitTestCase {
 
   /**
+   * The event dispatcher.
+   *
+   * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $eventDispatcher;
+
+  /**
    * The module handler used for testing.
    *
    * @var \Drupal\Core\Extension\ModuleHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
@@ -60,6 +68,8 @@ class PaymentMethodBaseUnitTest extends UnitTestCase {
   public function setUp() {
     parent::setUp();
 
+    $this->eventDispatcher = $this->getMock('\Symfony\Component\EventDispatcher\EventDispatcherInterface');
+
     $this->moduleHandler = $this->getMock('\Drupal\Core\Extension\ModuleHandlerInterface');
 
     $this->token = $this->getMockBuilder('\Drupal\Core\Utility\Token')
@@ -73,7 +83,7 @@ class PaymentMethodBaseUnitTest extends UnitTestCase {
     );
 
     $this->plugin = $this->getMockBuilder('\Drupal\payment\Plugin\Payment\Method\PaymentMethodBase')
-      ->setConstructorArgs(array(array(), '', $this->pluginDefinition, $this->moduleHandler, $this->token))
+      ->setConstructorArgs(array(array(), '', $this->pluginDefinition, $this->moduleHandler, $this->eventDispatcher, $this->token))
       ->setMethods(array('currencies', 'checkMarkup', 't'))
       ->getMock();
     $this->plugin->expects($this->any())
@@ -142,6 +152,9 @@ class PaymentMethodBaseUnitTest extends UnitTestCase {
     $this->moduleHandler->expects($this->once())
       ->method('invokeAll')
       ->with('payment_pre_execute');
+    $this->eventDispatcher->expects($this->once())
+      ->method('dispatch')
+      ->with(PaymentEvents::PAYMENT_PRE_EXECUTE);
     $this->plugin->executePayment($payment);
   }
 
@@ -180,6 +193,9 @@ class PaymentMethodBaseUnitTest extends UnitTestCase {
     $this->moduleHandler->expects($this->at(1))
       ->method('invokeAll')
       ->will($this->returnValue(array()));
+    $this->eventDispatcher->expects($this->exactly(2))
+      ->method('dispatch')
+      ->with(PaymentEvents::PAYMENT_EXECUTE_ACCESS);
     $account = $this->getMock('\Drupal\Core\Session\AccountInterface');
     $this->assertTrue($this->plugin->executePaymentAccess($payment, $account));
     $this->assertTrue($this->plugin->executePaymentAccess($payment, $account));
diff --git a/payment/lib/Drupal/payment/Tests/Plugin/Payment/Type/PaymentTypeBaseUnitTest.php b/payment/lib/Drupal/payment/Tests/Plugin/Payment/Type/PaymentTypeBaseUnitTest.php
index 3728574..bef79f5 100644
--- a/payment/lib/Drupal/payment/Tests/Plugin/Payment/Type/PaymentTypeBaseUnitTest.php
+++ b/payment/lib/Drupal/payment/Tests/Plugin/Payment/Type/PaymentTypeBaseUnitTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\payment\Tests\Plugin\Payment\Type;
 
+use Drupal\payment\Event\PaymentEvents;
 use Drupal\Tests\UnitTestCase;
 
 /**
@@ -15,6 +16,13 @@ use Drupal\Tests\UnitTestCase;
 class PaymentTypeBaseUnitTest extends UnitTestCase {
 
   /**
+   * The event dispatcher.
+   *
+   * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $eventDispatcher;
+
+  /**
    * The module handler.
    *
    * @var \Drupal\Core\Extension\ModuleHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
@@ -43,28 +51,20 @@ class PaymentTypeBaseUnitTest extends UnitTestCase {
    * {@inheritdoc}
    */
   public function setUp() {
+    $this->eventDispatcher = $this->getMock('\Symfony\Component\EventDispatcher\EventDispatcherInterface');
+
     $this->moduleHandler = $this->getMock('\Drupal\Core\Extension\ModuleHandlerInterface');
 
     $configuration = array();
     $plugin_id = $this->randomName();
     $plugin_definition = array();
     $this->paymentType = $this->getMockBuilder('\Drupal\payment\Plugin\Payment\Type\PaymentTypeBase')
-      ->setConstructorArgs(array($configuration, $plugin_id, $plugin_definition, $this->moduleHandler))
+      ->setConstructorArgs(array($configuration, $plugin_id, $plugin_definition, $this->moduleHandler, $this->eventDispatcher))
       ->setMethods(array('paymentDescription'))
       ->getMock();
   }
 
   /**
-   * @covers ::resumeContext
-   */
-  public function testResumeContext() {
-    $this->moduleHandler->expects($this->once())
-      ->method('invokeAll')
-      ->with('payment_type_pre_resume_context');
-    $this->paymentType->resumeContext();
-  }
-
-  /**
    * @covers ::setPayment
    * @covers ::getPayment
    */
@@ -75,4 +75,26 @@ class PaymentTypeBaseUnitTest extends UnitTestCase {
     $this->assertSame(spl_object_hash($this->paymentType), spl_object_hash($this->paymentType->setPayment($payment)));
     $this->assertSame(spl_object_hash($payment), spl_object_hash($this->paymentType->getPayment()));
   }
+
+  /**
+   * @covers ::resumeContext
+   *
+   * @depends testGetPayment
+   */
+  public function testResumeContext() {
+    $payment = $this->getMockBuilder('\Drupal\payment\Entity\Payment')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $this->paymentType->setPayment($payment);
+
+    $this->moduleHandler->expects($this->once())
+      ->method('invokeAll')
+      ->with('payment_type_pre_resume_context');
+
+    $this->eventDispatcher->expects($this->once())
+      ->method('dispatch')
+      ->with(PaymentEvents::PAYMENT_TYPE_PRE_RESUME_CONTEXT);
+
+    $this->paymentType->resumeContext();
+  }
 }
diff --git a/payment/lib/Drupal/payment/Tests/Plugin/Payment/Type/UnavailableUnitTest.php b/payment/lib/Drupal/payment/Tests/Plugin/Payment/Type/UnavailableUnitTest.php
index d7dc954..7eaf0b0 100644
--- a/payment/lib/Drupal/payment/Tests/Plugin/Payment/Type/UnavailableUnitTest.php
+++ b/payment/lib/Drupal/payment/Tests/Plugin/Payment/Type/UnavailableUnitTest.php
@@ -15,6 +15,13 @@ use Drupal\Tests\UnitTestCase;
 class UnavailableUnitTest extends UnitTestCase {
 
   /**
+   * The event dispatcher.
+   *
+   * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $eventDispatcher;
+
+  /**
    * The module handler used for testing.
    *
    * @var \Drupal\Core\Extension\ModuleHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
@@ -50,6 +57,8 @@ class UnavailableUnitTest extends UnitTestCase {
    * {@inheritdoc}
    */
   public function setUp() {
+    $this->eventDispatcher = $this->getMock('\Symfony\Component\EventDispatcher\EventDispatcherInterface');
+
     $this->moduleHandler = $this->getMock('\Drupal\Core\Extension\ModuleHandlerInterface');
 
     $this->translationManager = $this->getMockBuilder('\Drupal\Core\StringTranslation\TranslationManager')
@@ -60,7 +69,7 @@ class UnavailableUnitTest extends UnitTestCase {
     $plugin_id = $this->randomName();
     $plugin_definition = array();
     $this->paymentType = $this->getMockBuilder('\Drupal\payment\Plugin\Payment\Type\Unavailable')
-      ->setConstructorArgs(array($configuration, $plugin_id, $plugin_definition, $this->moduleHandler, $this->translationManager))
+      ->setConstructorArgs(array($configuration, $plugin_id, $plugin_definition, $this->moduleHandler, $this->eventDispatcher, $this->translationManager))
       ->setMethods(NULL)
       ->getMock();
   }
diff --git a/payment/lib/Drupal/payment/Tests/QueueUnitTest.php b/payment/lib/Drupal/payment/Tests/QueueUnitTest.php
new file mode 100644
index 0000000..94e3b0f
--- /dev/null
+++ b/payment/lib/Drupal/payment/Tests/QueueUnitTest.php
@@ -0,0 +1,115 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\payment\Tests\QueueUnitTest.
+ */
+
+namespace Drupal\payment\Tests;
+
+use Drupal\payment\Event\PaymentEvents;
+use Drupal\payment\Queue;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\payment\Queue
+ */
+class QueueUnitTest extends UnitTestCase {
+
+  /**
+   * The database connection.
+   *
+   * @var \Drupal\Core\Database\Connection|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $database;
+
+  /**
+   * The event dispatcher.
+   *
+   * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $eventDispatcher;
+
+  /**
+   * The module handler.
+   *
+   * @var \Drupal\Core\Extension\ModuleHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $moduleHandler;
+
+  /**
+   * The database connection.
+   *
+   * @var \Drupal\payment\Plugin\Payment\Status\PaymentStatusManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $paymentStatusManager;
+
+  /**
+   * The queue class under test.
+   *
+   * @var \Drupal\payment\Queue
+   */
+  protected $queue;
+
+  /**
+   * The unique ID of the queue (instance).|\PHPUnit_Framework_MockObject_MockObject
+   *
+   * @var string
+   */
+  protected $queueId;
+
+  /**
+   * {@inheritdoc}
+   */
+  static function getInfo() {
+    return array(
+      'description' => '',
+      'group' => 'Payment',
+      'name' => '\Drupal\payment\Queue unit test',
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function setUp() {
+    parent::setUp();
+    $this->database = $this->getMockBuilder('\Drupal\Core\Database\Connection')
+      ->disableOriginalConstructor()
+      ->getMock();
+
+    $this->eventDispatcher = $this->getMock('\Symfony\Component\EventDispatcher\EventDispatcherInterface');
+
+    $this->moduleHandler = $this->getMock('\Drupal\Core\Extension\ModuleHandlerInterface');
+
+    $this->paymentMethodManager = $this->getMock('\Drupal\payment\Plugin\Payment\Method\PaymentMethodManagerInterface');
+
+    $this->paymentStatusManager = $this->getMock('\Drupal\payment\Plugin\Payment\Status\PaymentStatusManagerInterface');
+
+    $this->queueId = $this->randomName();
+
+    $this->queue = new Queue($this->queueId, $this->database, $this->moduleHandler, $this->eventDispatcher, $this->paymentStatusManager);
+  }
+
+  /**
+   * @covers ::alterLoadedPaymentIds
+   */
+  public function testAlterLoadedPaymentIds() {
+    $category_id = $this->randomName();
+    $owner_id = $this->randomName();
+    $payment_ids = array($this->randomName());
+
+    $this->moduleHandler->expects($this->once())
+      ->method('alter')
+      ->with('payment_queue_payment_ids', $category_id, $owner_id, $payment_ids);
+
+    $this->eventDispatcher->expects($this->once())
+      ->method('dispatch')
+      ->with(PaymentEvents::PAYMENT_QUEUE_PAYMENT_IDS_ALTER);
+
+    $method = new \ReflectionMethod($this->queue, 'alterLoadedPaymentIds');
+    $method->setAccessible(TRUE);
+    $method->invoke($this->queue, $category_id, $owner_id, $payment_ids);
+  }
+
+}
diff --git a/payment/lib/Drupal/payment/Tests/QueueWebTest.php b/payment/lib/Drupal/payment/Tests/QueueWebTest.php
index a0ce06b..f0e9106 100644
--- a/payment/lib/Drupal/payment/Tests/QueueWebTest.php
+++ b/payment/lib/Drupal/payment/Tests/QueueWebTest.php
@@ -70,7 +70,7 @@ class QueueWebTest extends WebTestBase {
     $this->paymentMethodManager = \Drupal::service('plugin.manager.payment.method');
     $this->paymentStatusManager = \Drupal::service('plugin.manager.payment.status');
     $queue_id = $this->randomName();
-    $this->queue = new Queue($queue_id, $this->database, \Drupal::moduleHandler(), $this->paymentStatusManager);
+    $this->queue = new Queue($queue_id, $this->database, \Drupal::moduleHandler(), \Drupal::service('event_dispatcher'), $this->paymentStatusManager);
   }
 
   /**
diff --git a/payment/payment.api.php b/payment/payment.api.php
index 5081a64..6fdd393 100644
--- a/payment/payment.api.php
+++ b/payment/payment.api.php
@@ -76,7 +76,7 @@ function hook_payment_line_item_alter(array &$definitions) {
  * Alters payment type plugins.
  *
  * @param array $definitions
- *   Keys are plugin IDs. Values are plugin definitions.
+ *   Keys are plugein IDs. Values are plugin definitions.
  */
 function hook_payment_type_alter(array &$definitions) {
 }
@@ -85,13 +85,17 @@ function hook_payment_type_alter(array &$definitions) {
  * Responds to a payment status being set.
  *
  * @see Payment::setStatus()
+ * @see \Drupal\payment\Event\PaymentEvents::PAYMENT_STATUS_SET
+ * @see \Drupal\payment\Event\PaymentStatusSet
  *
  * @param \Drupal\payment\Entity\PaymentInterface $payment
  * @param \Drupal\payment\Plugin\Payment\Status\PaymentStatusInterface $previous_status
  *   The status the payment had before the new one was set. This may be
  *   identical to the current/new status.
  *
- * @return NULL
+ * @deprecated For proper dependency injection and testability, you are advised
+ * to use the \Drupal\payment\Event\PaymentEvents::PAYMENT_STATUS_SET Symfony
+ * event instead.
  */
 function hook_payment_status_set(PaymentInterface $payment, PaymentStatusInterface $previous_status = NULL) {
   // Notify the site administrator, for instance.
@@ -101,8 +105,14 @@ function hook_payment_status_set(PaymentInterface $payment, PaymentStatusInterfa
  * Executes before the payment type's original context is resumed.
  *
  * @see \Drupal\payment\Plugin\Payment\Type\PaymentTypeBase::resumeContext()
+ * @see \Drupal\payment\Event\PaymentEvents::PAYMENT_TYPE_PRE_RESUME_CONTEXT
+ * @see \Drupal\payment\Event\PaymentTypePreResumeContext
  *
  * @param \Drupal\payment\Entity\PaymentInterface $payment
+ *
+ * @deprecated For proper dependency injection and testability, you are advised
+ * to use the \Drupal\payment\Event\PaymentEvents::PAYMENT_PRE_RESUME_CONTEXT
+ * Symfony event instead.
  */
 function hook_payment_type_pre_resume_context(PaymentInterface $payment) {
   if ($payment->getStatus()->isOrHasAncestor('payment_success')) {
@@ -130,6 +140,12 @@ function hook_payment_type_pre_resume_context(PaymentInterface $payment) {
  *
  * @see \Drupal\payment\Plugin\Payment\Method\PaymentMethodBase::executePaymentAccess()
  * @see \Drupal\payment\Plugin\Payment\Method\PaymentMethodBase::executePaymentAccessEvent()
+ * @see \Drupal\payment\Event\PaymentEvents::PAYMENT_EXECUTE_ACCESS
+ * @see \Drupal\payment\Event\PaymentExecuteAccess
+ *
+ * @deprecated For proper dependency injection and testability, you are advised
+ * to use the \Drupal\payment\Event\PaymentEvents::PAYMENT_EXECUTE_ACCESS Symfony
+ * event instead.
  */
 function hook_payment_execute_access(PaymentInterface $payment, PaymentMethodInterface $payment_method, AccountInterface $account) {}
 
@@ -139,6 +155,12 @@ function hook_payment_execute_access(PaymentInterface $payment, PaymentMethodInt
  * @param \Drupal\payment\Entity\PaymentInterface $payment
  *
  * @see \Drupal\payment\Plugin\Payment\Method\PaymentMethodBase::executePayment()
+ * @see \Drupal\payment\Event\PaymentEvents::PAYMENT_PRE_EXECUTE
+ * @see \Drupal\payment\Event\PaymentPreExecute
+ *
+ * @deprecated For proper dependency injection and testability, you are advised
+ * to use the \Drupal\payment\Event\PaymentEvents::PAYMENT_PRE_EXECUTE Symfony
+ * event instead.
  */
 function hook_payment_pre_execute(PaymentInterface $payment) {}
 
@@ -151,6 +173,14 @@ function hook_payment_pre_execute(PaymentInterface $payment) {}
  *   The UID of the user for whom the payment should be available.
  * @param array $payment_ids
  *   The IDs of the payments that are available.
+ *
+ * @see \Drupal\payment\Event\PaymentEvents::PAYMENT_QUEUE_PAYMENT_IDS_ALTER
+ * @see \Drupal\payment\Event\PaymentQueuePaymentIdsAlter
+ *
+ * @deprecated For proper dependency injection and testability, you are advised
+ * to use the
+ * \Drupal\payment\Event\PaymentEvents::PAYMENT_QUEUE_PAYMENT_IDS_ALTER Symfony
+ * event instead.
  */
 function hook_payment_queue_payment_ids_alter($category_id, $owner_id, array &$payment_ids) {
   // Add or remove payment IDs. All IDs MUST be stored in the queue before they
diff --git a/payment_form/lib/Drupal/payment_form/Plugin/Payment/Type/PaymentForm.php b/payment_form/lib/Drupal/payment_form/Plugin/Payment/Type/PaymentForm.php
index 455f212..0a7d94a 100644
--- a/payment_form/lib/Drupal/payment_form/Plugin/Payment/Type/PaymentForm.php
+++ b/payment_form/lib/Drupal/payment_form/Plugin/Payment/Type/PaymentForm.php
@@ -29,13 +29,6 @@ use Symfony\Component\HttpKernel\KernelEvents;
 class PaymentForm extends PaymentTypeBase implements ContainerFactoryPluginInterface {
 
   /**
-   * The event dispatcher.
-   *
-   * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
-   */
-  protected $eventDispatcher;
-
-  /**
    * The field instance storage.
    *
    * @var \Drupal\Core\Entity\EntityStorageInterface
@@ -59,14 +52,14 @@ class PaymentForm extends PaymentTypeBase implements ContainerFactoryPluginInter
    * @param array $plugin_definition
    *   The plugin implementation definition.
    * @param \Drupal\Core\HttpKernel $http_kernel
-   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
+   *   The event dispatcher.
    * @param \Drupal\Core\Entity\EntityStorageInterface $field_instance_config_storage
    */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, HttpKernel $http_kernel, EventDispatcherInterface $event_dispatcher, ModuleHandlerInterface $module_handler, EntityStorageInterface $field_instance_config_storage) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition, $module_handler);
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, HttpKernel $http_kernel, ModuleHandlerInterface $module_handler, EventDispatcherInterface $event_dispatcher, EntityStorageInterface $field_instance_config_storage) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $module_handler, $event_dispatcher);
     $this->httpKernel = $http_kernel;
-    $this->eventDispatcher = $event_dispatcher;
     $this->fieldInstanceConfigStorage = $field_instance_config_storage;
   }
 
@@ -79,8 +72,8 @@ class PaymentForm extends PaymentTypeBase implements ContainerFactoryPluginInter
       $plugin_id,
       $plugin_definition,
       $container->get('http_kernel'),
-      $container->get('event_dispatcher'),
       $container->get('module_handler'),
+      $container->get('event_dispatcher'),
       $container->get('entity.manager')->getStorage('field_instance_config')
     );
   }
diff --git a/payment_form/lib/Drupal/payment_form/Tests/Plugin/Payment/Type/PaymentFormUnitTest.php b/payment_form/lib/Drupal/payment_form/Tests/Plugin/Payment/Type/PaymentFormUnitTest.php
index 2caef17..b1762e1 100644
--- a/payment_form/lib/Drupal/payment_form/Tests/Plugin/Payment/Type/PaymentFormUnitTest.php
+++ b/payment_form/lib/Drupal/payment_form/Tests/Plugin/Payment/Type/PaymentFormUnitTest.php
@@ -89,7 +89,7 @@ class PaymentFormUnitTest extends UnitTestCase {
       ->disableOriginalConstructor()
       ->getMock();
 
-    $this->paymentType = new PaymentForm(array(), 'payment_form', array(), $http_kernel, $this->eventDispatcher, $this->moduleHandler, $field_instance_config_storage);
+    $this->paymentType = new PaymentForm(array(), 'payment_form', array(), $http_kernel, $this->moduleHandler, $this->eventDispatcher, $field_instance_config_storage);
 
     $this->payment = $this->getMockBuilder('\Drupal\payment\Entity\Payment')
       ->disableOriginalConstructor()
diff --git a/payment_reference/lib/Drupal/payment_reference/Plugin/Payment/Type/PaymentReference.php b/payment_reference/lib/Drupal/payment_reference/Plugin/Payment/Type/PaymentReference.php
index 41c0924..4593750 100644
--- a/payment_reference/lib/Drupal/payment_reference/Plugin/Payment/Type/PaymentReference.php
+++ b/payment_reference/lib/Drupal/payment_reference/Plugin/Payment/Type/PaymentReference.php
@@ -13,6 +13,7 @@ use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\Core\Routing\UrlGeneratorInterface;
 use Drupal\payment\Plugin\Payment\Type\PaymentTypeBase;
 use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 use Symfony\Component\HttpFoundation\RedirectResponse;
 use Symfony\Component\HttpFoundation\Request;
 
@@ -67,11 +68,13 @@ class PaymentReference extends PaymentTypeBase implements ContainerFactoryPlugin
    * @param \Drupal\Core\HttpKernel $http_kernel
    * @param \Symfony\Component\HttpFoundation\Request $request
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
+   *   The event dispatcher.
    * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
    * @param \Drupal\Core\Entity\EntityStorageInterface $field_instance_config_storage
    */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, HttpKernel $http_kernel, Request $request, ModuleHandlerInterface $module_handler , UrlGeneratorInterface $url_generator, EntityStorageInterface $field_instance_config_storage) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition, $module_handler);
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, HttpKernel $http_kernel, Request $request, ModuleHandlerInterface $module_handler , EventDispatcherInterface $event_dispatcher, UrlGeneratorInterface $url_generator, EntityStorageInterface $field_instance_config_storage) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $module_handler, $event_dispatcher);
     $this->httpKernel = $http_kernel;
     $this->request = $request;
     $this->urlGenerator = $url_generator;
@@ -89,6 +92,7 @@ class PaymentReference extends PaymentTypeBase implements ContainerFactoryPlugin
       $container->get('http_kernel'),
       $container->get('request'),
       $container->get('module_handler'),
+      $container->get('event_dispatcher'),
       $container->get('url_generator'),
       $container->get('entity.manager')->getStorage('field_instance_config')
     );
diff --git a/payment_reference/lib/Drupal/payment_reference/Tests/Plugin/Payment/Type/PaymentReferenceUnitTest.php b/payment_reference/lib/Drupal/payment_reference/Tests/Plugin/Payment/Type/PaymentReferenceUnitTest.php
index 69b0a34..a1c4577 100644
--- a/payment_reference/lib/Drupal/payment_reference/Tests/Plugin/Payment/Type/PaymentReferenceUnitTest.php
+++ b/payment_reference/lib/Drupal/payment_reference/Tests/Plugin/Payment/Type/PaymentReferenceUnitTest.php
@@ -17,6 +17,13 @@ use Drupal\Tests\UnitTestCase;
 class PaymentReferenceUnitTest extends UnitTestCase {
 
   /**
+   * The event dispatcher used for testing.
+   *
+   * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $eventDispatcher;
+
+  /**
    * The field instance config used for testing.
    *
    * @var \Drupal\field\Entity\FieldInstanceConfigConfig|\PHPUnit_Framework_MockObject_MockObject
@@ -59,6 +66,8 @@ class PaymentReferenceUnitTest extends UnitTestCase {
    * {@inheritdoc}
    */
   protected function setUp() {
+    $this->eventDispatcher = $this->getMock('\Symfony\Component\EventDispatcher\EventDispatcherInterface');
+
     $url_generator = $this->getMockBuilder('\Drupal\Core\Routing\UrlGenerator')
       ->disableOriginalConstructor()
       ->getMock();
@@ -90,7 +99,7 @@ class PaymentReferenceUnitTest extends UnitTestCase {
       ->disableOriginalConstructor()
       ->getMock();
 
-    $this->paymentType = new PaymentReference(array(), 'payment_reference', array(), $http_kernel, $request, $this->moduleHandler, $url_generator, $field_instance_config_storage);
+    $this->paymentType = new PaymentReference(array(), 'payment_reference', array(), $http_kernel, $request, $this->moduleHandler, $this->eventDispatcher, $url_generator, $field_instance_config_storage);
 
     $this->payment = $this->getMockBuilder('\Drupal\payment\Entity\Payment')
       ->disableOriginalConstructor()
diff --git a/payment_reference/payment_reference.services.yml b/payment_reference/payment_reference.services.yml
index 09a4613..405de6c 100644
--- a/payment_reference/payment_reference.services.yml
+++ b/payment_reference/payment_reference.services.yml
@@ -1,4 +1,4 @@
 services:
   payment_reference.queue:
-    arguments: ['payment_reference', '@database', '@module_handler', '@plugin.manager.payment.status']
+    arguments: ['payment_reference', '@database', '@module_handler', '@event_dispatcher', '@plugin.manager.payment.status']
     class: Drupal\payment\Queue
\ No newline at end of file
