The Goal
Core Drupal Commerce provides Order Receipt functionality. An Order Receipt is an email notification sent to a customer when an order is placed. It lets the customer know that the order has been received and includes a summary of the order. For each Order Type, you can turn order receipts on/off and, if enabled, specify that a copy be sent to a specific recipient.
We would like to customize this functionality to suppress automatic order receipt emails for orders placed administratively/programatically. Additionally, we can add logic to vary the email copy recipient based on shipping destination (or some other order property.) For example, the order receipt could be sent to a standard Customer Service email address for domestic orders and an International Customer Service email address for international orders.
A Solution
Drupal Commerce core uses an event subscriber to send the order receipt email after an order is placed. We can disable this default event subscriber by simply disabling the, "Email the customer a receipt when an order is placed" setting for the order type. And then we can implement our own custom event subscriber with any logic we want.
To suppress order receipt emails placed administratively, we use a patch for this issue: Commerce Issue #3276744. This modifies the core OrderReceiptSubscriber to check for an skip_order_receipt
order data element.
To suppress order receipt emails for orders placed programmatically, we can use that skip_order_receipt
order data element.
Our implementation involves two components:
- A custom event subscriber class with service definition.
- Modification of any custom code in which the order "place" transition is programmatically applied.
Implementation:
The easiest way to implement our custom event subscriber is to start with a copy of the Commerce Core OrderReceiptSubscriber
class: Drupal\commerce_order\EventSubscriber\OrderReceiptSubscriber
Copy this file and add it to a custom module. Replace commerce_order
with your_module_name
in the namespace statement.
You can remove the entity type manager service and the following lines of code from the sendOrderReceipt method, since we won't rely on the order type configuration:
$order_type_storage = $this->entityTypeManager->getStorage('commerce_order_type');
/** @var \Drupal\commerce_order\Entity\OrderTypeInterface $order_type */
$order_type = $order_type_storage->load($order->bundle());
Additionally, remove this condition: $order_type->shouldSendReceipt()
. If you want to restrict receipt emails based on order type, replace the condition with one that checks the order type/bundle.
Add in any logic you need for setting the bcc for the order receipt and then send the email with this statement (where $bcc
is a valid email address or multiple, comma-separated email addresses or NULL
):
$this->orderReceiptMail->send($order, $order->getEmail(), $bcc);
For example, suppose we want to set the bcc based on billing address country. Our code might look something like this:
$bcc = 'sales@example.com';
if ($billing_profile = $order->getBillingProfile()) {
$billing_profile_address = $billing_profile->getAddress();
$domestic_countries = ['US', 'PR', 'CA'];
if (!in_array($billing_profile_address->getCountryCode(), $domestic_countries)) {
$bcc = 'international@example.com';
}
}
$this->orderReceiptMail->send($order, $order->getEmail(), $bcc);
Finally, don't forget to add an entry to your custom module's services.yml
file for your event subscriber:
my_module.order_receipt_subscriber:
class: Drupal\my_module\EventSubscriber\OrderReceiptSubscriber
arguments: ['@commerce_order.order_receipt_mail']
tags:
- { name: 'event_subscriber' }
Additionally...
If you do have custom code in which you "place" an order programmatically, like this:
$order->getState()->applyTransitionById('place');
And... you don't want that statement to automatically trigger an order receipt email, then add this statement right before the apply-transition statement:
$order->setData('skip_order_receipt', TRUE);
Your custom event subscriber should be checking that order data value.
Comments