Execution Flows

Rate calculation, shipment creation, tracking, and label generation

1. Rate Collection (Checkout)

During checkout, shipping rates are collected when the customer enters their shipping address. This flow is triggered by the Quote module's address rate request.

CHECKOUT SHIPPING STEP
=======================

Customer enters address
         |
         v
+---------------------------+
| Quote\Address             |
| ::collectShippingRates()  |
+------------+--------------+
             |
             v
+---------------------------+
| RateCollectorInterface    |
| ::collectRates($request)  |  --> Shipping::collectRates()
+------------+--------------+
             |
             v
+---------------------------+
| ScopeConfig::getValue()   |
| 'carriers/*' config       |
+------------+--------------+
             |
     +-------+-------+-------+-------+
     |       |       |       |       |
     v       v       v       v       v
 +------+ +------+ +------+ +------+ +------+
 | UPS  | | USPS | |FedEx | | Flat | | Free |
 | Rate | | Rate | | Rate | | Rate | | Ship |
 +--+---+ +--+---+ +--+---+ +--+---+ +--+---+
    |        |        |        |        |
    v        v        v        v        v
+---------------------------+
| CarrierResult             |
| ::appendResult()          |
+------------+--------------+
             |
             v
+---------------------------+
| Quote\Address             |
| ::setShippingRates()      |
+---------------------------+
             |
             v
+---------------------------+
| Displayed at checkout     |
| as radio button options   |
+---------------------------+

Key Method: Shipping::collectRates()

  1. Sets origin address from store config if not provided in request
  2. Gets list of enabled carriers from carriers/* config
  3. Iterates through carriers, calling collectCarrierRates()
  4. For each carrier: validates country availability, creates via factory, calls collectRates()
  5. Aggregates all rate results into CarrierResult
  6. Returns aggregated result to Quote for display

2. Single Carrier Rate Request

Shipping::collectCarrierRates($carrierCode, $request)
                   |
                   v
         +------------------+
         | prepareCarrier() |
         +--------+---------+
                  |
     +------------+------------+
     |                         |
     v                         v
+-----------+           +---------------+
| isActive? |--NO-----> | Skip carrier  |
+-----------+           +---------------+
     | YES
     v
+--------------------+
| checkAvailable     |
| ShipCountries()    |
+--------+-----------+
         |
    +----+----+
    |         |
    v         v
+-------+  +-------+
| true  |  | Error |---> append Error to result
+---+---+  +-------+
    |
    v
+------------------------+
| processAdditional      |
| Validation()           |
+--------+---------------+
         |
    +----+----+
    |         |
    v         v
+-------+  +-------+
| true  |  | false |---> skip carrier silently
+---+---+  +-------+
    |
    v
+------------------------+
| Check shipment_        |
| requesttype config     |
+--------+---------------+
         |
    +----+----+
    |         |
    v         v
+--------+ +----------------+
| false  | | true           |
+---+----+ | compose        |
    |      | Packages()     |
    |      +-------+--------+
    |              |
    +------+-------+
           |
           v
+------------------------+
| carrier->collectRates  |
| ($request)             |
+--------+---------------+
         |
         v
+------------------------+
| Result (methods/error) |
+--------+---------------+
         |
         v
+------------------------+
| getResult()->append    |
| Result($result)        |
+------------------------+

3. Shipment Creation (Admin)

Shipments are created from the admin order view. This flow handles the creation of the shipment record and optionally generates shipping labels.

ADMIN: Order View -> Ship
=========================

+----------------------------+
| Controller\Adminhtml\      |
| Order\Shipment\NewAction   |
+------------+---------------+
             |
             v
+----------------------------+
| ShipmentLoader::load()     |
| (builds Shipment model)    |
+------------+---------------+
             |
             v
+----------------------------+
| Render create form         |
| Block\Adminhtml\Create     |
+------------+---------------+
             |
             v [Submit Form]
+----------------------------+
| Controller\Adminhtml\      |
| Order\Shipment\Save        |
+------------+---------------+
             |
     +-------+--------+
     |                |
     v                v
+----------+   +------------------+
| No Label |   | Create Label?    |
+----+-----+   +--------+---------+
     |                  |
     |                  v
     |         +------------------+
     |         | Shipping\Labels  |
     |         | ::requestTo      |
     |         | Shipment()       |
     |         +--------+---------+
     |                  |
     |                  v
     |         +------------------+
     |         | carrier->        |
     |         | requestToShipment|
     |         +--------+---------+
     |                  |
     |                  v
     |         +------------------+
     |         | Store label data |
     |         | on Shipment      |
     |         +--------+---------+
     |                  |
     +--------+---------+
              |
              v
+----------------------------+
| ShipmentRepository::save() |
+------------+---------------+
             |
             v
+----------------------------+
| Create shipment tracks     |
| (tracking numbers)         |
+------------+---------------+
             |
             v
+----------------------------+
| Dispatch event:            |
| sales_order_shipment_      |
| save_after                 |
+----------------------------+

4. Tracking Lookup (Frontend)

Customers can view tracking information via a popup window accessed from their order confirmation email or account order history.

TRACKING POPUP
==============

Customer clicks tracking link
         |
         v
+----------------------------+
| Controller\Tracking\Popup  |
+------------+---------------+
             |
             v
+----------------------------+
| Load order/shipment/track  |
| from hash parameter        |
+------------+---------------+
             |
             v
+----------------------------+
| Info::getTrackingInfo()    |
+------------+---------------+
             |
     +-------+-------+
     |               |
     v               v
+----------+   +--------------+
| By Order |   | By Shipment  |
| ID       |   | ID           |
+----+-----+   +------+-------+
     |                |
     +-------+--------+
             |
             v
+----------------------------+
| Get all tracks for entity  |
| ShipmentTrackCollection    |
+------------+---------------+
             |
             v (for each track)
+----------------------------+
| CarrierFactory::create()   |
| ($carrierCode)             |
+------------+---------------+
             |
             v
+----------------------------+
| carrier->getTracking       |
| ($trackNumber)             |
+------------+---------------+
             |
             v
+----------------------------+
| Carrier calls external API |
| (UPS/FedEx/USPS/etc)       |
+------------+---------------+
             |
             v
+----------------------------+
| Return Tracking\Result     |
| with Status objects        |
+------------+---------------+
             |
             v
+----------------------------+
| Render Block\Tracking\     |
| Popup with tracking data   |
+----------------------------+

Tracking Status Fields

Basic Info

  • tracking - Tracking number
  • carrier - Carrier code
  • carrier_title - Display name
  • url - Carrier tracking URL

Delivery Info

  • status - Current status
  • deliverydate - Expected delivery
  • deliverytime - Delivery time
  • signedby - Signature

5. Shipping Label Generation

Shipping labels are generated during shipment creation when the carrier supports labels. This requires integration with the carrier's API.

LABEL GENERATION FLOW
=====================

+--------------------------------+
| Controller\Adminhtml\Order\    |
| Shipment\CreateLabel           |
+--------------+-----------------+
               |
               v
+--------------------------------+
| Shipping\Labels                |
| ::requestToShipment()          |
+--------------+-----------------+
               |
               v
+--------------------------------+
| Build Shipment\Request from    |
| order and package data         |
+--------------+-----------------+
               |
               v
+--------------------------------+
| CarrierFactory::create()       |
+--------------+-----------------+
               |
               v
+--------------------------------+
| AbstractCarrierOnline          |
| ::requestToShipment($request)  |
+--------------+-----------------+
               |
     +---------+----------+
     |                    |
     v                    v
+----------+      +----------------+
| Success  |      | Error          |
+----+-----+      +-------+--------+
     |                    |
     v                    v
+-------------+   +----------------+
| Get label   |   | Throw          |
| content &   |   | Localized      |
| tracking #  |   | Exception      |
+------+------+   +----------------+
       |
       v
+--------------------------------+
| Shipment::setShippingLabel()   |
| (store binary label data)      |
+--------------+-----------------+
               |
               v
+--------------------------------+
| Create ShipmentTrack with      |
| tracking number from response  |
+--------------+-----------------+
               |
               v
+--------------------------------+
| ShipmentRepository::save()     |
+--------------------------------+

Label Data Storage

Labels are stored as binary data in sales_shipment.shipping_label. The format (PDF, PNG, GIF) depends on the carrier's response. Use Shipment::getShippingLabel() to retrieve.

6. Shipment Report Aggregation (Cron)

A daily cron job aggregates shipment data for reporting. This runs at midnight.

<!-- etc/crontab.xml -->
<job name="aggregate_sales_report_shipment_data"
     instance="Magento\Shipping\Model\Observer"
     method="aggregateSalesReportShipmentData">
    <schedule>0 0 * * *</schedule>
</job>
CRON: aggregate_sales_report_shipment_data
==========================================

+--------------------------------+
| Magento\Shipping\Model\Observer|
| ::aggregateSalesReportShipment |
|    Data()                      |
+--------------+-----------------+
               |
               v
+--------------------------------+
| ResourceModel\Report\Shipping  |
| ::aggregate()                  |
+--------------+-----------------+
               |
               v
+--------------------------------+
| Query sales_shipment table     |
| Group by date, store, status   |
+--------------+-----------------+
               |
               v
+--------------------------------+
| Insert into                    |
| sales_shipping_aggregated      |
| _order table                   |
+--------------------------------+

Error Handling Patterns

Rate Collection Errors

When a carrier fails during rate collection, an Error result is appended:

$error = $this->_rateErrorFactory->create();
$error->setCarrier($this->_code);
$error->setCarrierTitle($this->getConfigData('title'));
$error->setErrorMessage(__('Carrier unavailable'));
return $error;

Country Restriction

When destination country is not allowed, carrier is skipped:

$result = $carrier->checkAvailableShipCountries($request);
if (false === $result) {
  // Skip silently (admin configured)
  return $this;
}

Label Generation Errors

Label failures throw LocalizedException:

if ($result->hasErrors()) {
  throw new LocalizedException(
    __($result->getErrors())
  );
}

Tracking Errors

Tracking failures use Tracking\Result\Error:

$error = $this->_trackErrorFactory->create();
$error->setTracking($trackNumber);
$error->setCarrier($this->_code);
$error->setErrorMessage(__('Unable to retrieve tracking'));
$result->append($error);