In Magento 1, retrieve the shipment model by its shipment increment ID, then iterate that shipment’s item collection. The collection contains only the products assigned to that shipment, so it prevents products from other shipments in the same order appearing again.
Load a shipment and list its products
Use loadByIncrementId() on sales/order_shipment. In this example, $shipid must contain a shipment increment ID such as 37006 or 37014, not the order increment ID.
<?php
$shipment = Mage::getModel('sales/order_shipment')
->loadByIncrementId($shipid);
$items = $shipment->getItemsCollection();
foreach ($items as $item) {
echo '<div>' . htmlspecialchars($item->getName(), ENT_QUOTES, 'UTF-8') . '</div>';
}
?>
The accepted SitePoint solution uses this same model-and-collection pattern; the original poster confirmed that it worked in the Magento 1 context (SitePoint discussion).
Keep shipment data separate from order data
| Collection or object | What it represents | Use when |
|---|---|---|
$shipment->getItemsCollection() |
Items assigned to one shipment | You need to show the products shipped under a particular shipment ID |
| Order-level item collection | All items belonging to the order | You need the complete order contents, regardless of shipment assignment |
| Tracking-data array | Carrier/tracking details collected by your template | You need tracking numbers or carrier information, not shipment products |
Magento’s order model exposes an order-level item collection, but that is not the shipment-specific collection needed here (OpenMage Magento 1.9 source). If an order is split between shipments 55555 and 77777, iterate the item collection from shipment 55555 for the first group and the collection from shipment 77777 for the second.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWhy the “call to a member function … on array” error occurs
The failed template built $shipTrack by looping over an order’s shipment collection and storing tracking details under each shipment increment ID. Each $_results value was therefore an array of tracking records, not a shipment object. Calling getAllItems() on that value caused the fatal error because PHP cannot invoke a Magento model method on an array.
Use the right value for each operation
- Use a shipment model to obtain shipped items:
$shipment->getItemsCollection(). - Use tracking records for carrier and tracking-number output.
- Do not assume an array of tracking details has shipment-model methods.
Displaying every item correctly
The forum snippet assigns $_product inside the loop and echoes after the loop. That placement displays only the final item. Put the output inside the loop when every shipped product must be shown.
<?php
$shipment = Mage::getModel('sales/order_shipment')
->loadByIncrementId($shipid);
foreach ($shipment->getItemsCollection() as $item) {
echo '<div class="shipment-item">';
echo '<span class="name">'
. htmlspecialchars($item->getName(), ENT_QUOTES, 'UTF-8')
. '</span>';
echo '</div>';
}
?>
Iterating all shipments for an order
If the page already has an order object and must render each shipment separately, keep the shipment loop and item loop nested. The inner loop must use the current shipment’s collection.
<?php
foreach ($order->getShipmentsCollection() as $shipment) {
echo '<h3>Shipment '
. htmlspecialchars($shipment->getIncrementId(), ENT_QUOTES, 'UTF-8')
. '</h3>';
foreach ($shipment->getItemsCollection() as $item) {
echo '<div>'
. htmlspecialchars($item->getName(), ENT_QUOTES, 'UTF-8')
. '</div>';
}
}
?>
Using the full order item collection inside that outer loop would repeat every order product under every shipment instead of preserving shipment membership.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Checks before deploying the template
- Confirm that the value passed to
loadByIncrementId()is the shipment increment ID, not the order increment ID. - Verify that the shipment exists before rendering its items; a missing or invalid ID should be handled by the surrounding template rather than assumed valid.
- Call
getItemsCollection()on the shipment model, not on tracking arrays. - Place per-item output inside the item loop.
- Test against the store’s local Magento 1 installation, especially if extensions or rewrites modify sales models.
What this pattern does—and does not—provide
The collection gives you the shipment’s item records and their product names. The basic example does not implement carrier display, tracking numbers, product images, custom options, or shipped quantities. Those require reading the corresponding fields and models in the target store’s shipment and tracking implementation.
This is Magento 1 syntax using Mage::getModel(); Magento 2 service contracts and factories are a different API and should not be substituted into this code.
Rank #4
The Bottom Line
For a product’s shipment association in Magento 1, work from the shipment model: load it by shipment increment ID and iterate getItemsCollection(). Keep tracking arrays and order-wide item collections out of that shipment-specific loop.
Quick Recap
Best Value
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




