I am attempting to develop a module that will send an email to a customer in my Commerce 2 store when that customer's order's status is updated to "Completed". I am basing my module off of the example shown in the handbook (https://docs.drupalcommerce.org/commerce2/developer-guide/orders/workflows/react-to-workflow-transitions)

Here's what I have so far:

File: /modules/custom/tracking_number_email/tracking_number_email.info.yml

name: Commerce Tracking Number Email
type: module
description: Uses an event subscriber to send an email with tracking number to customer after order status has been updated.
package: Commerce
core: 8.x

File: /modules/custom/tracking_number_email/tracking_number_email.services.yml

    class: Drupal\tracking_number_email\EventSubscriber\OrderFulfillmentSubscriber
    arguments: ['@language_manager', '@plugin.manager.mail']
      - { name: event_subscriber }

File: /modules/custom/tracking_number_email/src/EventSubscriber/TrackingNumberEmail.php


    namespace Drupal\tracking_number_email\EventSubscriber;

    use Drupal\state_machine\Event\WorkflowTransitionEvent;
    use Drupal\Core\Language\LanguageManagerInterface;
    use Drupal\Core\Mail\MailManagerInterface;
    use Drupal\Core\StringTranslation\StringTranslationTrait;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;

     * Sends an email when the order transitions to Fulfillment.
    class OrderFulfillmentSubscriber implements EventSubscriberInterface {

      use StringTranslationTrait;

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

       * The mail manager.
       * @var \Drupal\Core\Mail\MailManagerInterface
      protected $mailManager;

       * Constructs a new OrderFulfillmentSubscriber object.
       * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
       *   The language manager.
       * @param \Drupal\Core\Mail\MailManagerInterface $mail_manager
       *   The mail manager.
      public function __construct(
        LanguageManagerInterface $language_manager,
        MailManagerInterface $mail_manager
      ) {
        $this->languageManager = $language_manager;
        $this->mailManager = $mail_manager;

       * {@inheritdoc}
      public static function getSubscribedEvents() {
        $events = [
          'commerce_order.fulfill.post_transition' => ['sendEmail', -100],
        return $events;

       * Sends the email.
       * @param \Drupal\state_machine\Event\WorkflowTransitionEvent $event-       
       *   The transition event.
      public function sendEmail(WorkflowTransitionEvent $event) {
        // Create the email.
        $order = $event->getEntity();
        $to = $order->getEmail();
        $params = [
          'from' => $order->getStore()->getEmail(),
          'subject' => $this->t(
            'Regarding your order [#@number]',
            ['@number' => $order->getOrderNumber()]
          'body' => ['#markup' => $this->t(
            'Your order with #@number that you have placed with us has been processed and is awaiting fulfillment.',
            ['@number' => $order->getOrderNumber()]

        // Set the language that will be used in translations.
        if ($customer = $order->getCustomer()) {
          $langcode = $customer->getPreferredLangcode();
        else {
          $langcode = $this->languageManager->getDefaultLanguage()->getId();

        // Send the email.
        $this->mailManager->mail('commerce', 'receipt', $to, $langcode, $params);


I am receiving the following error message when this custom module is installed:

ReflectionException: Class Drupal\tracking_number_email\EventSubscriber\OrderFulfillmentSubscriber does not exist in ReflectionClass->__construct() (line 30 of /home1/mysite/public_html/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterEventSubscribersPass.php).

If I remove the tracking_number_email.services.yml the error goes away, but the module doesn't work (to be clear, it doesn't work whether or not that services.yml file is in place). I assume I have something erroneous in that services.yml file, but I am stuck trying to figure out what is wrong.

1 Answer 1


I didn't read through your code attempts, but have you evaluated Commerce Email yet? The module was basically written to serve this purpose.

  • Thanks for pointing out that module, I did not know that it existed. I installed it, but it appears that it only reacts to 3 events: Checkout Completion Register, Order Paid, and Order Placed. It does not appear that it has the capability to react to "Order Status Change" or better yet, "Order Fulfilled".
    – hockey2112
    Commented Sep 4, 2020 at 14:32
  • fwiw, creating a new plugin for Commerce Email to send an email on a specific state transition should be pretty easy. All you really need to do is copy the OrderPlaced plugin and change the event_name to the proper transition name: git.drupalcode.org/project/commerce_email/-/blob/8.x-1.x/src/… (If that's more than you bargained for, open a feature request in the module and we'll see what we can do. : ) Commented Sep 7, 2020 at 2:46
  • 1
    I ended up getting it to work after changing the filename to OrderFulfillmentSubscriber.php, to match with the class OrderFulfillmentSubscriber implements EventSubscriberInterface { portion of the code. Thanks!
    – hockey2112
    Commented Sep 16, 2020 at 20:30
  • @hockey2112 Rock on, way to stick with it! Commented Sep 17, 2020 at 2:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.