The DC2x deployment experience can be improved by adding site builder configurable Order Receipt email - subject header - and - from header - customization capabilities.

It seems like this can be implemented with an additional field for the order receipt email subject line in the store entity, viewed in configuration at:

{site}/admin/commerce/config/store-types/online/edit/form-display

and edited by the site builder in associated admin UI at:

{site}/store/*/edit

The field can include @variables for placement of the store-name and the order-number in the subject line - (@storename and @ordernumber), and support in the function - sendOrderReceipt(WorkflowTransitionEvent $event) - within:

{site}/modules/commerce/modules/order/src/EventSubscriber/OrderReceiptSubscriber.php

-

At present, the sendOrderReceipt() function uses a hard-coded email subject header text string when assembling the email subject header (see code excerpt).


    $params = [
      'headers' => [
        'Content-Type' => 'text/html',
      ],
      'from' => $order->getStore()->getEmail(),
      'subject' => $this->t('Order #@number confirmed', ['@number' => $order->getOrderNumber()]),
      'order' => $order,
    ];

Instead that string could be retrieved from a field in the store entity which can include the @variables in it. Of course the store entity subject field can include help text regarding the @variables. The "from" header could be similarly enhanced to provide a:

t( '"@storename" <@from>', ... )

construct to build the from header in the style ' "store name" '.

-

At present I've built a small module that implements a simplified version of this, although it doesn't include use of an additional store entity field for subject string.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

websiteworkspace created an issue. See original summary.

bojanz’s picture

Title: commerce 2.x order receipt email headers - need customizability » Provide a way to customize the order receipt email subject

Clarifying the title.

Sut3kh’s picture

Simple workaround:

/**
 * Implements hook_mail_alter().
 */
function mymodule_mail_alter(array &$message) {
  // Order receipt.
  if ($message['id'] === 'commerce_order_receipt') {
    /** @var \Drupal\commerce_order\Entity\OrderInterface $order */
    $order = $message['params']['order'];
    
    // Change the email subject.
    // @todo Remove this if/when it becomes configurable.
    //   https://www.drupal.org/project/commerce/issues/2924159
    $message['subject'] = t('Some other email subject #@number', [
      '@number' => $order->getOrderNumber(),
    ]);
  }
}

It does feel like this should be an option however the difficulty with using configuration is translation and a twig template wouldn't really fit so i'm not sure if there is a simple solution other than a hook (which basically exists now via hook_mail_alter).

gmem’s picture

Status: Active » Needs review
FileSize
6.33 KB

Here's a pretty basic patch addressing this issue, which adds a field to the store entity with a subject input and ability to use @orderid for the order number. It also changes the from field in the email to the format <@storename> <@email> instead of just the email.

Status: Needs review » Needs work

The last submitted patch, 4: email-subject-2924159-4.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

gmem’s picture

Status: Needs work » Needs review
FileSize
6.31 KB

Fixed a typo in the plugin type for the entity field.

Status: Needs review » Needs work

The last submitted patch, 6: email-subject-2924159-6.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

mandclu’s picture

I whole heartedly agree that the changes proposed here are needed. That said, the patch from #6 wouldn't apply against 8.x-2.17, although to be fair I do have another patch already applied. Will try again with a clean version.

mandclu’s picture

Looks like the code to send the receipt email has been significantly refactored, so the patch will need to be updated accordingly. Happy to take a stab at it, but I can't get to it right away.

Neograph734’s picture

I was not aware of this issue (was searching for email headers), but I have a separate issue in which I proposed to include the store name in the From header. The solution is different though.

lunk rat’s picture

I want to chime in with another use-case for this feature.

My team is building a Commerce site with two Commerce Stores: (1) Events registrations, and (2) Physical products. For our Events registration store, we want the subject line to say:

Your Registration Confirmation #@order_number from @storename

But for the Physical products store, we want it to say:

Order #@order_number from @storename

I understand that a custom module with hook_mail_alter() will get the job done, but I wanted to advocate for the approach proposed here. I think adding a configuration field to Store entities is the correct approach.

So if anyone feels like refactoring #6 to pass current tests, your contribution would be valued by many Commerce users I am sure of it.

anruether’s picture

You can use easy_email for this. But you need 1.x-dev (or 2.x), the commerce override is not present in beta2:

  1. Install easy_email module
  2. Create email template via /admin/structure/email-templates/templates/add
  3. Add order reference field to template
  4. Install easy_email_override module
  5. Add email override via: /admin/structure/email-templates/overrides/add (Under Email to Override choose Commere order: Order receipt)
  6. Under parameter mapping choose your reference field under Order
  7. Now you can customize your email via the easy_email template, e.g. by using a token for your store ID: [easy_email:field_cci_order:entity:store_id]
lisastreeter’s picture

I found this issue when my hook_mail_alter stopped working after switching to Symfony mailer. As a result, I agree that it would be good to have a solution in Commerce Core that does not rely on that hook.

As mentioned in comment #10, there is another issue which specifically addresses the "From header" updates, so I think we should keep that change separate. Issue #3121168: Include the store name in the email From header

Also, I think it would be better to use the Token service instead of @order_number in the string. (In the previous comment #12, Easy Email was mentioned as a token-based option.)

Given that Order Types already have settings related to the order receipt emails, I think it makes sense to include the Receipt Subject as part of that configuration rather than creating a new field on Stores. To me, this also just feels more like configuration than content. I'm not sure whether this approach would work for the use-case described in comment #11, but it seems likely that there would be different order types for event registrations vs. physical products.

I've created an updated patch, which does not include test coverage.

fenstrat’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests
FileSize
9.78 KB
1.78 KB

I also hit this when switching to symfony_mailer.

Agree with @lisastreeter that this should use the token service and that this config belongs on the order type.

Attached has a stab at a test, it should be all that's needed. Also adds an post_update hook to add the receipt_subject to config.

Status: Needs review » Needs work

The last submitted patch, 14: 2924159-14.patch, failed testing. View results

fenstrat’s picture

Status: Needs work » Needs review
FileSize
10.33 KB
833 bytes

Trying test with installing token as OrderTokensTest does. Unfortunately something is borked with my local when running commerce kernel tests so can't easily verify this will work.

DamienMcKenna’s picture

Shouldn't the update script set existing emails to have the old subject of 'Order #@number confirmed'? Also, would it be worth skipping the $this->token->replace() piece if the subject is empty?

    /** @var \Drupal\commerce_order\Entity\OrderTypeInterface $order_type */
    $order_type = $this->orderTypeStorage->load($order->bundle());
    $subject = $order_type->getReceiptSubject();
    if (!empty($subject)) {
      $subject = $this->token->replace($subject, [
        'commerce_order' => $order,
      ]);
    }
    // Provide a default value if the subject line was blank.
    if (empty($subject)) {
      $subject = $this->t('Order #@number confirmed', ['@number' => $order->getOrderNumber()]);
    }
DamienMcKenna’s picture

I read through the rest of the changes and understand the direction that was being taken, so the update script works fine.

Here's the minor code change from #17, along with a minor tidying.

jsacksick’s picture

I don't think this will make it into core TBH. If we start introducing a setting for that, then I guess we should add 50 other settings :).

For site builders not comfortable writing little code to override the order receipt subject, Commerce Email can be used instead of the default core order receipt email.

The Commerce Email module also lets you customize the content of the email as well.

DamienMcKenna’s picture

The decision on what to include vs not include in Commerce is a bit confusing. I would wager the overwhelming majority of sites want emails created as part of the commerce transaction process, so why not have it fully functioning out of the box, including the ability to modify the email subject (this issue)? OTOH the vast majority of sites don't need the ability to create separate stores, but that functionality is built in and mandatory.

SocialNicheGuru’s picture

I assume that you would either use the patch in this issue or "Commerce Email" module not both.

jsacksick’s picture

Status: Needs review » Fixed

Decided to go ahead and commit a slightly modified version of the patch from comment #18. I actually wondered about getting the token service from the container for people that decorated the Order receipt mail service... But, this alone wouldn't work, so this could potentially be a BC even though I believe people decorating the order receipt mail service shouldn't really extend the base class but rather just implement the interface.

jsacksick’s picture

Note that I got rid of the post update function which is unnecessary.

  • jsacksick committed deed7007 on 8.x-2.x
    Issue #2924159 followup by jsacksick: Properly access the profile view...

  • jsacksick committed 796a8689 on 3.0.x
    Issue #2924159 followup by jsacksick: Properly access the profile view...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

Anybody’s picture

@jsacksick trying to translate the subject I just saw that the field was introduced as "string" in the config schema. but must be "label" to be translatable. That's an impediment for multilingual commerce projects. I think it's quite clearly wrong?

Could you perhaps take a look at #3380805: Commerce Order config value receiptSubject ("Subject for the order receipt email") is not translatable and if the change is clear and fine, merge that?

Thank you in advance! :)