4

I'm using the following code to place an order programmatically in Magento 2:

    // Configure the quote
    $quote = $this->cart->getQuote();
    $quote->setInventoryProcessed(false);
    $quote->setPaymentMethod('custom_gateway');
    $quote->save();

    // Set the payment method
    $payment = $quote->getPayment();
    $payment->importData(['method' => 'custom_gateway']);

    // Update the quote
    $quote->collectTotals()->save();

    // Place the order
    $this->cartManagement->placeOrder($quote->getId());

This code is creating the order as expected, but is also sending an email to the shopper.

I would like to send the confirmation email at a later stage in the process, only when the payment has been confirmed.

How can I place an order without notifying the customer?

  • Seem that you're implementing the online payment? – Khoa TruongDinh Apr 13 '17 at 13:33
  • Did you find a solution at last? :( – ermannob Jun 22 '17 at 15:13
1

We can set the flag for order: $order->setCanSendNewEmailFlag(false)

We can see some good examples for online payments:

vendor/magento/module-quote/Observer/Webapi/SubmitObserver.php

vendor/magento/module-paypal/Model/Payflowlink.php
  • If the placeOrder() function sends an email, I don't see how I can set the flag after the order has been created. I have just tried the following and the email is still sent: $order = $this->quoteManagement->submit($quote); $order->setCanSendNewEmailFlag(false); – David Fiaty Apr 13 '17 at 13:51
  • It seems that once the order has been placed, it's too late to set the flag. Could you please suggest a way to create an order where your suggestion would be usable? – David Fiaty Apr 13 '17 at 13:54
  • I think we can try with plugin: Magento\Sales\Api\OrderManagementInterface::place(). Should use afterPlace() plugin. We can set $order->setCanSendNewEmailFlag(false). – Khoa TruongDinh Apr 13 '17 at 13:54
  • I am not sure about how to implement this. Would you please have a short example? – David Fiaty Apr 13 '17 at 14:01
  • in the Payflow extension you mention, this is what happens: $order = $payment->getOrder(); $order->setCanSendNewEmailFlag(false); So basically the order already exists, that's why you can set a flag. In my case, the order is created from a quote so you can't set the flag before the order is created. Is there any way to disable email notification at the quote level for example? – David Fiaty Apr 13 '17 at 14:09
1

The solution is to use this:

use Magento\Quote\Model\QuoteManagement;
...
// Create order from quote
$order = $this->quoteManagement->submit($quote);

QuoteManagement will not send an order until you call

use Magento\Sales\Model\Order\Email\Sender\OrderSender;
...

// Send the email when desired
$this->orderSender->send($order);
0

have you checked this: admin->Stores->Configuration->Sales->Sales Emails->Order and set Enabled as no

now check !!

  • Thank you for the info. Is there no way to do that for a single order without impacting the global configuration? – David Fiaty Apr 13 '17 at 13:31
  • Basically I am working on a custom payment gateway. If I do what you suggest from a global config, what happens to other payment gateways that need this on? – David Fiaty Apr 13 '17 at 13:34
0

I was looking for this and I have came up with this:

  1. Most solutions out there is doing something like this:

    $cartId = $this->cartManagementInterface->createEmptyCart();

    ... ...

    $orderId = $this->cartManagementInterface->placeOrder($quote->getId());

Which is the easiest solution in my opinion.

But this method triggers an observer:

sales_model_service_quote_submit_success

Which is responsible for sending the emails.

vendor/magento/module-quote/Observer/SubmitObserver.php

This means you can't do $order->setCanSendNewEmailFlag(false) before the emails is sent at least once.

For this what I did was :

  1. When creating the cart do:

$cart->setCanSendNewEmailFlag(false);

  1. Make a new observer that will be executed before Quote module:

  2. On the observer do:

    if($quote->getCanSendNewEmailFlag() == false){ $order->setCanSendNewEmailFlag(false);

With this now you can set the setCanSendNewEmailFlag before sending an email.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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