I had exactly the same problem and it seems that there is solution without extending the API!
The shipment API has an undocumented function called sendInfo. Thanks to [cameronhimself][1] for pointing this.
public function sendInfo($shipmentIncrementId, $comment = '')
So you need something like this (for SOAP V1)
try {
$orderIncrementId = "Your ORDER ID";
$itemarray = array('3' => '3', '4' => '5'); //your order items id's and qty to ship
$comments = "some optional comments";
$email = FALSE; //this is important! You do NOT want to sent the shipping email (email is sent with tracking number later)
$includeComments = TRUE; //if you want to sent the comments with the email to customer
$shipment = array($orderIncrementId, $itemarray, $comments, $email, $includeComments);
$nship = $proxy->call($sessionId, 'sales_order_shipment.create', $shipment); //create the shippment. $nship is the new shipment id
$proxy->call($sessionId, 'sales_order_shipment.addTrack', array('shipmentIncrementId' => $nship, 'carrier' => 'custom', 'title' => 'CARRIER TITLE', 'trackNumber' => 'YOURTARCKINGNUMBER')); //add the tracking number to shippment
$proxy->call($sessionId, 'sales_order_shipment.sendInfo', array('shipmentIncrementId' => $nship)); //this is the fun part. Send the email of the shippment WITH the tracking number
} catch (Exception $e) {
echo 'Shipment creation failed on order '. $orderIncrementId . ': ', $e->getMessage();
}
Maybe you run into the same issue i had. I got emails, not containing the correct updated informations.
i figured out (Magento 1.7.2) that the Email for tracking is generated even before the tracking information was saved. Normally all works fine in default, but sometimes it happened, that the email sending is generated before the tracking is generated or updated.
What i were doing is to add an additional $this->save()
in app/code/core/Mage/Sales/Model/Order/Shipment.php
at the function addTrack
right before the return
statement.
For sure i didn't do this in the core file itself, i've cloned it into app/code/local/Mage/Sales/Model/Order/Shipment.php
My addTrack looks like this now:
public function addTrack(Mage_Sales_Model_Order_Shipment_Track $track)
{
$track->setShipment($this)
->setParentId($this->getId())
->setOrderId($this->getOrderId())
->setStoreId($this->getStoreId());
if (!$track->getId()) {
$this->getTracksCollection()->addItem($track);
}
/**
* Track saving is implemented in _afterSave()
* This enforces Mage_Core_Model_Abstract::save() not to skip _afterSave()
*/
$this->_hasDataChanges = true;
/**
* Added additional $this->save(); to have the new data for shippment
* tracking already in the Mage_Sales_Model_Order_Shipment object.
* If this would not happen, the tracking mails generated may have old
* or wrong data regarding carrier title.
*/
$this->save();
return $this;
}
EDIT 3nd May 2016:
Hi Scot,
in app/code/local/Mage/Sales/Model/Order/Shipment/Api/V2.php
and app/code/local/Mage/Sales/Model/Order/Shipment/Api.php
i've REMOVED $shipment->sendEmail($email, ($includeComment ? $comment : ''));
in the create() function at the try/catch block right after the ->save();
public function create($orderIncrementId, $itemsQty = array(), $comment = null, $email = false,
$includeComment = false
) {
$order = Mage::getModel('sales/order')->loadByIncrementId($orderIncrementId);
/**
* Check order existing
*/
if (!$order->getId()) {
$this->_fault('order_not_exists');
}
/**
* Check shipment create availability
*/
if (!$order->canShip()) {
$this->_fault('data_invalid', Mage::helper('sales')->__('Cannot do shipment for order.'));
}
/* @var $shipment Mage_Sales_Model_Order_Shipment */
$shipment = $order->prepareShipment($itemsQty);
if ($shipment) {
$shipment->register();
$shipment->addComment($comment, $email && $includeComment);
if ($email) {
$shipment->setEmailSent(true);
}
$shipment->getOrder()->setIsInProcess(true);
try {
$transactionSave = Mage::getModel('core/resource_transaction')
->addObject($shipment)
->addObject($shipment->getOrder())
->save();
} catch (Mage_Core_Exception $e) {
$this->_fault('data_invalid', $e->getMessage());
}
return $shipment->getIncrementId();
}
return null;
}
But i've added the email send in addTrack()
public function addTrack($shipmentIncrementId, $carrier, $title, $trackNumber)
{
$shipment = Mage::getModel('sales/order_shipment')->loadByIncrementId($shipmentIncrementId);
/* @var $shipment Mage_Sales_Model_Order_Shipment */
if (!$shipment->getId()) {
$this->_fault('not_exists');
}
$carriers = $this->_getCarriers($shipment);
if (!isset($carriers[$carrier])) {
$this->_fault('data_invalid', Mage::helper('sales')->__('Invalid carrier specified.'));
}
$track = Mage::getModel('sales/order_shipment_track')
->setNumber($trackNumber)
->setCarrierCode($carrier)
->setTitle($title);
$shipment->addTrack($track);
try {
$shipment->save();
$track->save();
if(!$shipment->getEmailSent()) {
$shipment->sendEmail(true, $shipment->getCommentsCollection());
$shipment->setEmailSent(true);
$shipment->save();
}
} catch (Mage_Core_Exception $e) {
$this->_fault('data_invalid', $e->getMessage());
}
return $track->getId();
}
Hope i didn't mix up something again.
Best Answer
Even though a long time has passed, answering for anyone else that might need it. When calling the ship api at:
/V1/order/{orderId}/ship
, there is anotify
key you can pass, thus causing Magento to send a notification, so your JSON might look something like:See more here: https://devdocs.magento.com/swagger/#/salesShipOrderV1/salesShipOrderV1ExecutePost