I am making a connector for Magento, where orders from Magento are pushed into our system, then get shipments created that need to be pulled back into Magento and converted to the right format. In Magento 2, this is accomplished with shipRepo->create()

I believe, but I'm struggling to find the correct Magento 1 solution. I have the order's increment ID from the original order, so I'm trying to use that. Right now here is what I'm trying:

$order = Mage::getModel('sales/order')->loadByIncrementId($orderId);
if($order->canShip()) {
        $itemQty =  $order->getItemsCollection()->count();
        $shipment = Mage::getModel('sales/service_order', $order)->prepareShipment($itemQty);
        $shipment = new Mage_Sales_Model_Order_Shipment_Api();
        $shipmentId = $shipment->create($orderId, $itemQty,null,true,false);

However, when I try this out, I get a data_invalid error. What am I doing wrong?

PS: I'm basing my code off of this inchoo post and this stack overflow post but I'm pretty sure it's still failing on the create method.

I'm curious why we set $shipment twice. Does that first assignment actually accomplish anything?

  • More Details needed. Where exactly are your files located and what have you changed? – Black Sep 18 '18 at 17:26
  • I'm making my own module and this is a function within a cron job. The file is under {baseDir}/app/code/local/Namespace/Module/Model is that what you're asking? I don't know what you mean by what have I changed... – ctrl-z pls Sep 18 '18 at 17:42
  • Please try with "$shipmentId = $shipment->create($orderId, $itemQty,null,false,false);" instead of "$shipmentId = $shipment->create($orderId, $itemQty,null,true,false);" in your code. Also refer magento.stackexchange.com/questions/58606/… – Chirag Rajput Sep 19 '18 at 6:54
  • So that still didn't work, I guess the problem is with $itemQty because when I replaced it with array() then the shipment created, but I have no control over the data in it. Like what if it was a partial shipment and I didn't actually ship all of it? – ctrl-z pls Sep 19 '18 at 17:00

Ok after a lot of trial and error I think I figured it out.

First of all, I've seen this method all over the place, but it is a mess. I would like to say I managed to cleaned it up into something that is actually usable.

This line: $itemQty = $order->getItemsCollection()->count(); sets $itemQty to a number, a count, but the create() method requires an array! That was ultimately the reason I was getting a data_invalid error, and when I changed

$shipment->create($orderId, $itemQty,null,true,false);


$shipment->create($orderId, array(),null,true,false);

it kind of fixed things, in that I no longer got an error. But I don't want to just blindly accept all quantities on the shipment. I want to accept only what is actually on the shipment (duh) so I had to figure out the right way to do it.

First thing to do was make a $itemQtys array of the format


Then just create the API and shipment. But their way of making the API is very... not Magento-y. So I changed it from

$shipment = new Mage_Sales_Model_Order_Shipment_Api();


$newShip = Mage::getModel('sales/order_shipment_api');

For me, it looked something like this:

$order = Mage::getModel('sales/order')->loadByIncrementId($orderId);
if($order->canShip()) {
    $itemQtys = array();

    //cycle through the items on the shipment and add them to the array
    //note: you must previously define $shipItems from your shipment
    foreach($shipItems as $newItem) {
        $itemQtys[$newItem->getOrderItemId()] = $newItem->getQty();

    //create the shipment
    $shipApi= Mage::getModel('sales/order_shipment_api');
    $shipId = $shipApi->create($orderId, $itemQtys);

    //get the actual shipment if you want to further manipulate it
    $magShip = Mage::getModel('sales/order_shipment')->loadByIncrementId($shipId);

I also experimented with using prepareShipment in the form of

$magShip = Mage::getModel('sales/service_order', $order)->prepareShipment($itemQtys);

However, this did not succeed in actually creating the shipment, nor was it necessary in my solution, so I'm still not totally sure what it's supposed to be used for.


From the original post, only the last two lines did anything. To create a shipment programmatically, create a $itemQtys array and then call the create function.

Source code was also useful from here.

| improve this answer | |

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.