Question

I recently implemented custom code from here to stop Paypal orders on my magento from being invoiced automatically. However, the new order confirmation email is no longer being sent. I have to go the order in admin panel and manually press 'send email' for every order to send the order confirmation email.

The code in question:

Create a file Wfh_DisableAutoInvoice.xml in app/etc/modules/ and put the following code.

<?xml version="1.0"?>
<config>
<modules>
    <Wfh_DisableAutoInvoice>
        <active>true</active>
        <codePool>local</codePool>
    </Wfh_DisableAutoInvoice>
</modules>
</config>

Create a file config.xml in app/code/local/Wfh/DisableAutoInvoice/etc/ and put the following code.

<?xml version="1.0"?>
<config>
<modules>
    <Wfh_DisableAutoInvoice>
        <version>0.1.0</version>
    </Wfh_DisableAutoInvoice>
</modules>
<global>
    <models>
        <disableautoinvoice>
            <class>Wfh_DisableAutoInvoice_Model</class>
            <resourceModel>disableautoinvoice_mysql4</resourceModel>
        </disableautoinvoice>
        <sales>
            <rewrite>
        <order_payment>Wfh_DisableAutoInvoice_Model_Sales_Order_Payment</order_payment>
            </rewrite>
        </sales>
    </models>
</global>
</config> 

Create a file Payment.php in app/code/local/Wfh/DisableAutoInvoice/Model/Sales/Order/ and put the following code.

class Wfh_DisableAutoInvoice_Model_Sales_Order_Payment extends     Mage_Sales_Model_Order_Payment
{   

/**
 * Authorize or authorize and capture payment on gateway, if applicable
 * This method is supposed to be called only when order is placed
 *
 * @return Mage_Sales_Model_Order_Payment
 */
public function place()
{
    Mage::dispatchEvent('sales_order_payment_place_start', array('payment' => $this));
    $order = $this->getOrder();

    $this->setAmountOrdered($order->getTotalDue());
    $this->setBaseAmountOrdered($order->getBaseTotalDue());
    $this->setShippingAmount($order->getShippingAmount());
    $this->setBaseShippingAmount($order->getBaseShippingAmount());

    $methodInstance = $this->getMethodInstance();
    $methodInstance->setStore($order->getStoreId());
    $orderState = Mage_Sales_Model_Order::STATE_NEW;
    $stateObject = new Varien_Object();

    /**
     * Do order payment validation on payment method level
     */
    $methodInstance->validate();
    $action = $methodInstance->getConfigPaymentAction();
    if ($action) {
        if ($methodInstance->isInitializeNeeded()) {
            /**
             * For method initialization we have to use original config value for payment action
             */
            $methodInstance->initialize($methodInstance->getConfigData('payment_action'), $stateObject);
        } else {
            $orderState = Mage_Sales_Model_Order::STATE_NEW;
            switch ($action) {
                case Mage_Payment_Model_Method_Abstract::ACTION_ORDER:
                    $this->_order($order->getBaseTotalDue());
                    break;
                case Mage_Payment_Model_Method_Abstract::ACTION_AUTHORIZE:
                    $this->_authorize(true, $order->getBaseTotalDue()); // base amount will be set inside
                    $this->setAmountAuthorized($order->getTotalDue());
                    break;
                case Mage_Payment_Model_Method_Abstract::ACTION_AUTHORIZE_CAPTURE:
                    $this->setAmountAuthorized($order->getTotalDue());
                    $this->setBaseAmountAuthorized($order->getBaseTotalDue());
                    $this->capture(null);
                    break;
                default:
                    break;
            }
        }
    }

    $this->_createBillingAgreement();

    $orderIsNotified = null;
    if ($stateObject->getState() && $stateObject->getStatus()) {
        $orderState      = $stateObject->getState();
        $orderStatus     = $stateObject->getStatus();
        $orderIsNotified = $stateObject->getIsNotified();
    } else {
        $orderStatus = $methodInstance->getConfigData('order_status');
        if (!$orderStatus) {
            $orderStatus = $order->getConfig()->getStateDefaultStatus($orderState);
        } else {
            // check if $orderStatus has assigned a state
            $states = $order->getConfig()->getStatusStates($orderStatus);
            if (count($states) == 0) {
                $orderStatus = $order->getConfig()->getStateDefaultStatus($orderState);
            }
        }
    }
    $isCustomerNotified = (null !== $orderIsNotified) ? $orderIsNotified : $order->getCustomerNoteNotify();

    $message = $order->getCustomerNote();
    // add message if order was put into review during authorization or capture
    if ($order->getState() == Mage_Sales_Model_Order::STATE_PAYMENT_REVIEW) {
        if ($message) {
            $order->addStatusToHistory($order->getStatus(), $message, $isCustomerNotified);
        }
    } elseif ($order->getState() && ($orderStatus !== $order->getStatus() || $message)) {
        // add message to history if order state already declared
        $order->setState($orderState, $orderStatus, $message, $isCustomerNotified);
    } elseif (($order->getState() != $orderState) || ($order->getStatus() != $orderStatus) || $message) {
        // set order state
        $order->setState($orderState, $orderStatus, $message, $isCustomerNotified);
    }

    Mage::dispatchEvent('sales_order_payment_place_end', array('payment' => $this));

    return $this;
}


/**
 * Capture the payment online
 * Does not create invoice automatically for order
 * Updates transactions hierarchy, if required
 * Updates payment totals, updates order status and adds proper comments
 *
 * TODO: eliminate logic duplication with registerCaptureNotification()
 *
 * @return Mage_Sales_Model_Order_Payment
 * @throws Mage_Core_Exception
 */
public function capture($invoice)
{

    $invoice = null;
    $order = $this->getOrder();

    $amountToCapture = $this->_formatAmount($order->getBaseGrandTotal());

    $paidWorkaround = (float)$amountToCapture;
    $this->_isCaptureFinal($paidWorkaround);

    $this->_generateTransactionId(
        Mage_Sales_Model_Order_Payment_Transaction::TYPE_CAPTURE,
        $this->getAuthorizationTransaction()
    );

    Mage::dispatchEvent('sales_order_payment_capture', array('payment' => $this, 'invoice' => $invoice));

    $status = true;
    if (!$this->getIsTransactionPending()) {
        // attempt to capture: this can trigger "is_transaction_pending"
        $this->getMethodInstance()->setStore($order->getStoreId())->capture($this, $amountToCapture);

        $transaction = $this->_addTransaction(
            Mage_Sales_Model_Order_Payment_Transaction::TYPE_CAPTURE,
            $invoice,
            true
        );

        if ($this->getIsTransactionPending()) {
            $message = Mage::helper('sales')->__('Capturing amount of %s is pending approval on gateway.', $this->_formatPrice($amountToCapture));
            $state = Mage_Sales_Model_Order::STATE_PAYMENT_REVIEW;
            if ($this->getIsFraudDetected()) {
                $status = Mage_Sales_Model_Order::STATUS_FRAUD;
            }
        } else { // normal online capture: invoice is marked as "paid"
            $message = Mage::helper('sales')->__('Captured amount of %s online.', $this->_formatPrice($amountToCapture));
            $state = Mage_Sales_Model_Order::STATE_NEW;
            $this->_updateTotals(array('base_amount_paid_online' => $amountToCapture));
        }
        if ($order->isNominal()) {
            $message = $this->_prependMessage(Mage::helper('sales')->__('Nominal order registered.'));
        } else {
            $message = $this->_prependMessage($message);
            $message = $this->_appendTransactionToMessage($transaction, $message);
        }
        $order->setState($state, $status, $message);

        return $this;
    }
    Mage::throwException(
        Mage::helper('sales')->__('The transaction "%s" cannot be captured yet.', $amountToCapture)
    );
}

/**
 * Process a capture notification from a payment gateway for specified amount
 * Does not create an invoice automatically if the amount if the amount covers the order base grand total completely
 * Updates transactions hierarchy, if required
 * Prevents transaction double processing
 * Updates payment totals, updates order status and adds proper comments
 *
 * TODO: eliminate logic duplication with capture()
 *
 * @param float $amount
 * @param bool $skipFraudDetection
 * @return Mage_Sales_Model_Order_Payment
 */
public function registerCaptureNotification($amount, $skipFraudDetection = false)
{

    $this->_generateTransactionId(Mage_Sales_Model_Order_Payment_Transaction::TYPE_CAPTURE,
        $this->getAuthorizationTransaction()
    );

    $order   = $this->getOrder();
    $amount  = (float)$amount;
    $invoice = null;

    // register new capture
    if (!$invoice) {
        $isSameCurrency = $this->_isSameCurrency();
        if (!$isSameCurrency && !$this->_isCaptureFinal($amount)) {
            if (!$skipFraudDetection || !$isSameCurrency) {
                $this->setIsFraudDetected(true);
            }
            $this->_updateTotals(array('base_amount_paid_online' => $amount));
        }
    }

    $status = true;
    if ($this->getIsTransactionPending()) {
        $message = Mage::helper('sales')->__('Capturing amount of %s is pending approval on gateway.', $this->_formatPrice($amount));
        $state = Mage_Sales_Model_Order::STATE_PAYMENT_REVIEW;
        if ($this->getIsFraudDetected()) {
            $message = Mage::helper('sales')->__('Order is suspended as its capture amount %s is suspected to be fraudulent.', $this->_formatPrice($amount, $this->getCurrencyCode()));
            $status = Mage_Sales_Model_Order::STATUS_FRAUD;
        }
    } else {
        $message = Mage::helper('sales')->__('Registered notification about captured amount of %s.', $this->_formatPrice($amount));
        $state = Mage_Sales_Model_Order::STATE_NEW;
        if ($this->getIsFraudDetected()) {
            $state = Mage_Sales_Model_Order::STATE_PAYMENT_REVIEW;
            $message = Mage::helper('sales')->__('Order is suspended as its capture amount %s is suspected to be fraudulent.', $this->_formatPrice($amount, $this->getCurrencyCode()));
            $status = Mage_Sales_Model_Order::STATUS_FRAUD;
        }
    }

    $transaction = $this->_addTransaction(Mage_Sales_Model_Order_Payment_Transaction::TYPE_CAPTURE, $invoice, true);
    $message = $this->_prependMessage($message);
    $message = $this->_appendTransactionToMessage($transaction, $message);
    $order->setState($state, $status, $message);
    return $this;
}
}

Why could this code be affecting this? Like status for paypal orders now go to pending as they should from pending payment.

Checking paypal, the payment status there is complete. No errors are being logged either.

Was it helpful?

Solution

In the file:

/app/code/core/Mage/Paypal/Model/ipn.php

Magento by default checks that an invoice exists and that an email has not already been sent. By removing $invoice && from line 493 and the if statement from line 457 Got emails to send for Paypal orders.

Now, I was aware of when magento sent the order confirmation emails for Paypal orders, I proceeded to amend a section of the registerCaptureNotification function in my payment.php to the following:

public function registerCaptureNotification($amount, $skipFraudDetection = false)
{

    $this->_generateTransactionId(Mage_Sales_Model_Order_Payment_Transaction::TYPE_CAPTURE,
        $this->getAuthorizationTransaction()
    );

    $order   = $this->getOrder();
    $amount  = (float)$amount;
    $invoice = null;

    // register new capture
    if (!$invoice) {
        $isSameCurrency = $this->_isSameCurrency();
        if (!$isSameCurrency && !$this->_isCaptureFinal($amount)) {
            if (!$skipFraudDetection || !$isSameCurrency) {
                $this->setIsFraudDetected(true);
            }
            $this->_updateTotals(array('base_amount_paid_online' => $amount));
        }
    }

    $status = true;
    $letsEmail = false;
    if ($this->getIsTransactionPending()) {
        $message = Mage::helper('sales')->__('Capturing amount of %s is pending approval on gateway.', $this->_formatPrice($amount));
        $state = Mage_Sales_Model_Order::STATE_PAYMENT_REVIEW;
        $letsEmail = true;
        if ($this->getIsFraudDetected()) {
            $message = Mage::helper('sales')->__('Order is suspended as its capture amount %s is suspected to be fraudulent.', $this->_formatPrice($amount, $this->getCurrencyCode()));
            $status = Mage_Sales_Model_Order::STATUS_FRAUD;
            $letsEmail = false;
        }
    } else {
        $message = Mage::helper('sales')->__('Registered notification about captured amount of %s.', $this->_formatPrice($amount));
        $state = Mage_Sales_Model_Order::STATE_NEW;
        $letsEmail = true;
        if ($this->getIsFraudDetected()) {
            $state = Mage_Sales_Model_Order::STATE_PAYMENT_REVIEW;
            $message = Mage::helper('sales')->__('Order is suspended as its capture amount %s is suspected to be fraudulent.', $this->_formatPrice($amount, $this->getCurrencyCode()));
            $status = Mage_Sales_Model_Order::STATUS_FRAUD;
            $letsEmail = false;
        }
    }

    $transaction = $this->_addTransaction(Mage_Sales_Model_Order_Payment_Transaction::TYPE_CAPTURE, $invoice, true);
    $message = $this->_prependMessage($message);
    $message = $this->_appendTransactionToMessage($transaction, $message);
    $order->setState($state, $status, $message);
    if ($letsEmail === true && !$order->getEmailSent()){
         $order->queueNewOrderEmail()->addStatusHistoryComment(
                Mage::helper('paypal')->__('Notified Customer')
            )
            ->setIsCustomerNotified(true)
            ->save();
    }

    return $this;
}

Setting a letsEmail flag to true when a positive capture occurs and false for negative/fraudulent capture. Then along with the following:

!$order->getEmailSent()

To check that an email has not already been sent, I did an if statement so when the flag is true and no email had been sent for the order, create a new order status history comment, with 'notified customer' as the text and send a new order confirmation email to the customer.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top