Automatic invoicing in magento

2019-05-09 12:29发布

问题:

I have created new custom product type which extends virtual product in magento. Now I would like to block automatic invoicing for online payments eg. paypal when order contains at least one custom product type. All orders with such product have to be invoiced manually. How should I resolve this?

回答1:

The best approach to this would be register an Observer to an Event thrown during the payment capture process, but I'm not seeing too many relevant ones unfortunately. You could try sales_order_invoice_save_before to intercept the save(), but I'm not keen on that as it may confuse the controller(s) as to why the invoice save failed.

Looking through the Paypal code, you will see in Mage_Paypal_Model_Ipn::_processOrder() that it calls $this->_registerPaymentCapture() on success, which in turn calls $payment->registerCaptureNotification().

Mage_Sales_Model_Order_Payment::registerCaptureNotification($amount) creates a new invoice if one doesn't already exist and the payment is the full amount of the order. It uses the _isCaptureFinal($amount) method to verify this.

One option would be to extend Mage_Sales_Model_Order_Payment and override _isCaptureFinal($amount) with code along the lines of:

foreach($this->getOrder()->getAllItems() as $oOrderItem){
  if($oOrderItem()->getProduct()->getTypeId() == 'your_custom_product_type'){
    return false;
  }
}
return parent::_isCaptureFinal($amountToCapture);

Don't forget the final call to parent!!

You would do all this in a custom module (start with the ModuleCreator if you want), and insert the following into the config.xml

<global>
    <models>
        <modulename>
            <class>Namespace_Modulename_Model</class>
        </modulename>
        <sales>
            <rewrite>
                <order_payment>Namespace_Modulename_Model_Order_Payment</order_payment>
            </rewrite>
        </sales>
    </models>

Standard disclaimers apply, you're messing with funds transactions here, so makes sure that you test it really really thoroughly.

Note that this approach will apply to all payment methods that call Mage_Sales_Model_Order_Payment::registerCaptureNotification($amount), not just Paypal.

Good Luck,
JD