7

I'm trying to write a custom module for Magento that when certain items are ordered and payment has been made, posts to our clothing supplier's site with details of the ordered item, delivery address and other data in either XML or JSON format.

Whilst I've been a web developer for some years, I haven't worked with the Magento system much before and was wondering if anyone could point me in the right direction?

I think I've found a hook (sales_order_invoice_save_after) that could do the trick but not too sure it's the right one or how to begin putting the code together!

Thanks in advance

  • An event and an observer is a good start. Hook up an observer to that event. The observer is basically a method that is called upon dispatching the event. Inside this method you can retrieve the order model object and parse it to be able to send it to your third party API. Take a look at this answer to retrieve the order object and call your API. Be careful with this event, as it triggers everytime something in the invoice changes (look here, here) – Vic Jun 30 '15 at 17:34
  • Free upvote to help you get to 50 rep so you can comment. – pspahn Jun 30 '15 at 22:47
4

We currently have an observer that sends our order data to our Oracle DB. It observes checkout_onepage_controller_success_action and the code formats the order into JSON and transmits it via a web service to our Oracle DB. We are using 1.0.4.1 so I'm not sure if it would work with your version. Anyway, here is a skeleton of it, I took out the meat ;-)

This fires when the order success page shows.

<?php

class NA_OrderTransmit_Model_Observer {

    public function SendOrder(Varien_Event_Observer $observer) {
        // This is the function called in the checkout_onepage_controller_success action
        // your order data is available by loading the order like this:
        $order = new Mage_Sales_Model_Order();
        $magento_order_id = Mage::getSingleton('checkout/session')->getLastRealOrderId();
        $order->loadByIncrementId($magento_order_id);
    }
}

You can then format your JSON and use cURL to send your order data just like we do.

And here is the Config file:

<config>
    <modules>
        <NA_OrderTransmit>
            <version>1.0</version>
        </NA_OrderTransmit>
    </modules>
    <global>
        <models>
            <ordertransmit>
                <class>NA_OrderTransmit_Model</class>
            </ordertransmit>
        </models>          
        <events>
          <checkout_onepage_controller_success_action>
                <observers>
                        <email_test>
                                <type>singleton</type>
                                <class>ordertransmit/observer</class>
                                <method>SendOrder</method>
                        </email_test>
                </observers>
          </checkout_onepage_controller_success_action>
        </events>
     </global>
</config>
  • Would the order not be available as part of $observer? – Robbie Averill Aug 11 '15 at 21:50
  • Not that I'm aware of, I did not write this module, it was done by a contractor 5 yrs ago. He also modified tons of core code so I'm not saying he was perfect. That is why we're still on 1.0.4.1 – MB34 Aug 11 '15 at 22:21
3

The event will depend of the moment that you would like to send the order to supplier.

If is when the order is placed the best is sales_place_order_after.
If is when the order is paid them you can use sales_order_payment_pay.

The sales_order_payment_pay is dispatched after each invoice is paid and updates the totals of payment. So you can check the amount_paid of payment against total order amount. A point of attention is that the order total paid amount is not updated at this moment because the order totals is updated after this event. You can verify this in the following code of Mage_Sales_Model_Order_Invoice::pay

$this->getOrder()->getPayment()->pay($this); //dispatch in payment the event sales_order_payment_pay

//This updates the order total paid
$this->getOrder()->setTotalPaid(
    $this->getOrder()->getTotalPaid()+$this->getGrandTotal()
);
$this->getOrder()->setBaseTotalPaid(
    $this->getOrder()->getBaseTotalPaid()+$this->getBaseGrandTotal()
);
Mage::dispatchEvent('sales_order_invoice_pay', array($this->_eventObject=>$this));

For best performance you also should use some internal queue/cron to send this data asynchronous to the supplier. So if the external service is down you will not affect your store.

2

The correct event for this task is sales_place_order_after. You can access the order with $observer->getEvent()->getOrder() IIRC (I am on mobile atm). If you have further questions, just ask :)

To the other guy from the other answer (can't see your name right now, sorry): there is a tool on github that is called mageaudit. This will help you identify the core modifications, and let you fix them & update your system ;)

1

I think using any observer for this which observers an event in the frontend is badly wrong. Whatever event you are listening too, takes place, while the customer is waiting for his success page or anything else.

This means, when your web service is broken or just bad performs your customers may wait 30+ seconds and after your timeout they finally get's hat they want.

The alternative is to either listen on the payment event, which is triggered by IPN or something alike or:

implement queue/cron

Just add a new attribute to the order, run a cron every few minutes and transfer everything which isn't marked as transfered yet.

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.