# TrackEasy: Carriers, Delivery Dates and Tracking Page

> Connect carrier APIs, match custom carriers, understand tracking refreshes, calculate delivery dates, and set up the tracking page.

---

This page is part of the [TrackEasy guide](/docs/trackeasy). Start there for what the extension does, installation and the frequently asked questions.

## Add a carrier and connect its API credentials

Connecting a carrier lets TrackEasy poll for live tracking events and update delivery dates automatically.

![Setup: Carrier Tracking APIs](images/config-carrier.png)

### How to set it up

1. Go to:
   Stores > Configuration > Moogento > TrackEasy > Setup: Carrier Tracking APIs

2. Open **New Carrier** in the carrier table. Select the carrier type and fill in the credentials for that carrier:

   **FedEx**
   - Type key: `fedex`
   - Client ID - your FedEx Developer Portal OAuth 2.0 Client ID
   - Client Secret - your FedEx Developer Portal OAuth 2.0 Client Secret
   - Sandbox - toggle on to use `apis-sandbox.fedex.com` for testing; turn off for production

   **UPS**
   - Type key: `ups`
   - Access Key - UPS Legacy Access License Number
   - Username - UPS account username
   - Password - UPS account password
   - UPS API Environment is configured separately at Stores > Configuration > Moogento > TrackEasy > UPS: Live Calls > UPS API Environment (default: sandbox)

   **DHL**
   - Type key: `dhl`
   - API Key - DHL API key from the DHL Developer Portal
   - Uses the EU endpoint (`api-eu.dhl.com`) by default; DHL eCommerce Americas OAuth is also supported via the generic config

   **Australia Post / StarTrack**
   - Type key: `auspost` or `startrack`
   - API Key - key from the AusPost Developer Centre

   **Team Global Express (TGE, formerly Toll)**
   - Type key: `toll`
   - Ask Team Global Express to add the `MOOGENTO` profile to your MyTeamGE eTrade account. They send you a Client ID and Client Secret for it.
   - Client ID - the MyTeamGE API Client ID
   - Client Secret - the MyTeamGE API Client Secret
   - API environment - **Production (live API)** for your real consignments; **Sandbox** uses the TGE test gateway
   - Message header - filled in for you with the `MOOGENTO` SourceSystemCode and MessageSender. Leave it as it is unless TGE registers a different sender for you.
   - **Firewall:** the TGE API runs on port 6930 (`api.teamglobalexp.com:6930`), not the usual 443. Your server must allow outgoing connections on port 6930. On cPanel servers with CSF, add `6930` to `TCP_OUT` (and `TCP6_OUT`) in `/etc/csf/csf.conf` and run `csf -r`. If the **Test API** button says the request "could not reach the native gateway", this port is the usual cause.
   - TrackEasy shows the full scan history for each consignment. Scan locations show as suburb and state, for example "Hazelmere, WA".
   - The "Electronic Billing Transfer" scan that TGE raises when a consignment is created is not shown to customers, and it does not move the order to Shipped. The order moves to Shipped when the carrier reports the parcel has actually been collected.
   - To test the connection, use a consignment number from the last few days, then follow [Test Team Global Express with a recent consignment](#test-team-global-express-with-a-recent-consignment).

   **USPS**
   - Type key: `usps`
   - Sandbox - toggle on to use the USPS sandbox endpoint for testing; turn off for production
   - By default, TrackEasy reads the USPS User ID from Sales > Delivery Methods > USPS (`carriers/usps/userid`). When that setting is populated, a message confirms the credentials are being used and no further fields are required.
   - **Use custom TrackEasy API** checkbox - appears when Magento USPS credentials are already configured; tick it to override with TrackEasy-specific credentials instead.
   - When the checkbox is ticked (or no Magento USPS credentials exist), two additional fields appear:
     - **Username/Tracking API Key** - your USPS client ID (REST) or User ID (XML)
     - **Password/Tracking API Secret Key** - your USPS client secret (REST only; not used in XML mode)
   - **USPS API Mode** dropdown - also visible when custom credentials are in use: **REST (OAuth v3)** (default) or **XML (TrackV2)**. REST uses OAuth 2.0 with a client ID and secret; XML uses the legacy TrackV2 API with a User ID only.

   **Royal Mail / Evri** - link-only. The carrier appears in the list and displays the public tracking URL for the shipment; no API credential fields are required or shown in the admin.

   **17Track** - universal fallback
   - Type key: `17track`
   - The 17Track panel appears only after you select **17Track** from **New Carrier**. It starts disabled so you can add and test the API Security Key before enabling live fallback lookups.
   - To remove the integration, delete its row and save the configuration. The row stays absent after reload and **17Track** returns to the **New Carrier** menu.
   - API Security Key - your 17Track account API key, copied from the API backend (API settings) at 17track.net, not the Shopper Center
   - This is an optional, paid fallback that activates only when native carrier APIs and Magento core tracking return no usable data. It covers 2,100+ carriers globally and auto-detects carrier by tracking number, so any carrier not listed above can still be tracked.
   - New accounts receive 200 free tracking numbers as of January 7, 2026. Each number you register consumes from your account quota.
   - Some carriers, including USPS, require extra setup in your 17Track account. USPS tracking is not available on the free quota - it needs a paid 17Track plan plus an authorized USPS Mailer ID (MID) configured in your 17Track account. If USPS lookups are rejected, open Carrier Management in the 17Track dashboard, enable USPS under Special Carriers, and confirm your account has the paid plan and available quota. This is a 17Track account requirement, not a TrackEasy setting.

3. Click **Save Config**.
4. Run `php bin/magento cache:clean`.

### Notes

- Obtain credentials before starting: FedEx uses OAuth 2.0 from the FedEx Developer Portal (`https://developer.fedex.com/`); UPS uses a legacy Access Key from `https://developer.ups.com/`; AusPost uses an API key from `https://developers.auspost.com.au/`; Team Global Express (formerly Toll) uses a MyTeamGE Client ID and Client Secret issued by TGE for the `MOOGENTO` profile, and needs outgoing port 6930 open on your server; 17Track uses an API Security Key from `https://www.17track.net`.
- Use the **Test** button next to each carrier row to verify credentials before saving. For 17Track, the Test Token button validates your key via the quota check endpoint without consuming any tracking numbers.
- For FedEx and UPS, always start with sandbox credentials; switch to production once a live tracking number returns results.
- Carrier events are cached in the database. A test using the CLI command `bin/magento moogento:trackeasy:carrier:test --carrier=fedex --tracking=TRACKINGNUMBER` returns the raw API response to help diagnose credential problems.
- **17Track fallback**: This optional provider activates only when native tracking and Magento core carrier APIs return no usable data. It is not polled like primary carriers; instead, it is queried as a last resort when tracking data is missing. Webhook support is available - after configuring 17Track in TrackEasy, register the webhook URL from the admin settings panel in your 17Track dashboard under Webhook settings to receive automatic push updates when a package status changes.

---

## Test Team Global Express with a recent consignment

Do this once after saving the TGE credentials. It proves the Client ID, Client Secret, environment and port 6930 all work together.

### How to set it up

1. Confirm the carrier row is saved with **API environment** set to **Production (live API)**. Sandbox only returns TGE test data, so a real consignment will not be found there.
2. Ask your server host to allow outgoing connections on port 6930 if you have not already (see the firewall note above).
3. Pick a consignment that TGE handled in the last few days. A very old consignment may no longer be available from TGE.
4. Type that consignment number into the tracking number field on the TGE row and click **Test API**. A successful test returns the scans for the parcel, each with a date and a "Suburb, STATE" location.
5. Or run the same check from the command line:

   ```
   php bin/magento moogento:trackeasy:carrier:test --carrier=toll --tracking=YOUR_CONSIGNMENT_NUMBER
   ```

6. Add the same consignment number as a tracking number on a test order, open its tracking page, and confirm the scan history and timeline appear.

### Notes

- If the test says the request "could not reach the native gateway", port 6930 is blocked. If it says the credentials were rejected, check that TGE added the `MOOGENTO` profile to your MyTeamGE account and that you copied the Client ID and Client Secret exactly.
- The "Electronic Billing Transfer" scan is hidden from customers on purpose. You will not see it on the tracking page, and it does not move the order to Shipped.

---

## Match custom carriers and tracking numbers

Shipments saved with Magento's **Custom Value** carrier have no built-in carrier. TrackEasy decides which carrier name, logo, tracking link and live lookup to use from the shipment title, the tracking number and your own rules. Magento's saved carrier and title are never changed.

### How to set it up

1. Go to:
   Stores > Configuration > Moogento > TrackEasy > Carriers: Identity Mapping

2. Set:
   - **Identify carrier from the shipment title** - Yes reads the carrier name out of the title, for example "FedEx Express" or "Team Global Express".
   - **When carrier title and tracking number disagree** - choose what happens when the title names one carrier and the tracking number clearly belongs to another. For example, the title says FedEx but the number is a recognised UPS format. Choose whether TrackEasy keeps the carrier named in the title or switches to the one the number identifies.
   - **Custom carrier rules** - add your own rows that map a tracking number pattern to one of the carriers TrackEasy offers. Your rows are checked first. The pre-filled rows cover both USPS number patterns and DHL eCommerce numbers that start with GM. Delete a row to stop using that format, or use **Reset to default** to bring it back.

3. Save Config and run `php bin/magento cache:clean`.

### Notes

- Complete UPS 1Z numbers, LaserShip 1LS numbers and international postal numbers ending in US, GB, AU, CA, IE or IT identify their carrier. 22-digit USPS numbers and OnTrac numbers are used only when the title names no carrier, because other carriers hand parcels over under the same formats.
- Once a carrier is identified, tracking updates come from that carrier's own API, or from 17TRACK if it has no direct connection. If neither can track it, TrackEasy shows the shipment without live updates rather than asking the wrong carrier.
- Updates already saved from another carrier are replaced on the next lookup. Delivered shipments keep what they have.

---

## How often tracking refreshes

Each undelivered parcel is checked about every 15 minutes while it is moving. Once it is more than 3 days old, or the carrier has given a delivery date, it is checked about once an hour. Checking stops when the parcel is delivered, or 30 days after the tracking number was added.

The tracking page also refreshes a parcel when a customer or your team opens it, so a page that is open never shows a stale scan for long. Admins can click **Refresh tracking events** on an order's TrackEasy timeline to fetch an update for that one order straight away.

Refreshing relies on Magento cron and the message queue consumer, as described in [Carrier refresh queue and cron schedule](/docs/trackeasy-reference-and-troubleshooting#carrier-refresh-queue-and-cron-schedule). Carrier rate limits can slow a refresh down; the next check picks up anything missed.

---

## What the timeline shows

The timeline has five steps: **Ordered**, **Packed**, **Shipped**, **Out for delivery** and **Delivered**. The Shipped, Out for delivery and Delivered steps follow the carrier's scans, so a customer sees progress as soon as the carrier records it. If you do not use a Packed status, that step is removed automatically.

A shipping label created by you or your shipping software does not count as the carrier moving the parcel. Carriers such as UPS, FedEx and USPS report "Label created" before they have the parcel; TrackEasy waits for the first real carrier scan, such as a pickup or a hub arrival, before it treats the parcel as on its way.

Until the carrier provides its own delivery date, the timeline shows your estimated delivery date and labels it **Expected**. Once the carrier gives a date, the label changes to **Delivered By**, and it stays that way after delivery.

### When an order is marked Delivered

Once a carrier is tracking a parcel, TrackEasy marks the order Delivered only when the carrier confirms delivery. A passed delivery date alone does not mark it.

The setting behind this (`moogento_trackeasy/moo/auto_set_delivered`, shown as **Show: DBD on & after the DBD**) is under Stores > Configuration > Moogento > TrackEasy > Design: Timeline steps > DBD: Delivered By Date. It only applies to parcels that have no live tracking, for example a carrier you have not connected. For those, the order is marked Delivered the day after the delivery date. If you want every order to move to Delivered on carrier confirmation, connect each carrier you ship with, or add 17TRACK as a fallback.

---

## Configure delivery date (DBD) calculation

The Delivered By Date drives the timeline milestone, the orders-grid DBD column, and delivery-update emails.

![Design: Timeline - DBD settings](images/config-design_timeline.png)

### How to set it up

1. Go to:
   Stores > Configuration > Moogento > TrackEasy > Design: Timeline steps > DBD: Delivered By Date

2. Set:
   - **Set: DBD (Delivered By Date)** - choose the calculation method:
     - From order date (fixed offset)
     - From shipment date (offset recalculated when a shipment is created)
     - Combined (sets an initial estimate from order date, then recalculates from shipment date)
   - **Estimate: DBD how many days from Order date** - default 14 days
   - **Estimate: DBD how many days from Shipment date** - used when the shipment-date option is active
   - **Update: DBD based on shipper API response?** = Yes - let carrier events override the estimate (default: Yes)
   - **Hide: DBD until the order has a shipment?** = Yes if you don't want to show an estimate before a shipment is created

3. Under **SBD: Shipped By Date**:
   - **Show: Shipped By Date (SBD)?** = Yes to display a "Shipped By" milestone before shipment (default: No)
   - **Estimate: Shipped By Date how many days from Order date** - default 5 days

4. Under **Steps**, set which order statuses advance each milestone:
   - **Packed status(es)** - select statuses like "Picked" or "Packed" that should move the timeline to the Packed point
   - **Shipped status(es)** - select statuses like "Complete" or "Shipped" that mark the order as shipped on the timeline

5. Save Config.

### Notes

- If no Packed status applies to your workflow, leave the Packed status field empty - the Packed milestone is removed from the timeline automatically.
- When **Update DBD from API** is on and a carrier scan provides an updated ETA, the DBD changes and a delivery-update email is sent if that feature is enabled.
- The DBD column appears in the admin orders grid. Enable the calendar-style display at Stores > Configuration > Moogento > TrackEasy > Design: Orders Page > Style DBD in the Orders page.

---

## Set up the standalone tracking page

The standalone tracking page is a public URL sent to customers so they can check their shipment without logging in.

![Design: Tracking Pages](images/config-page_layout_standalone.png)

### How to set it up

1. Go to:
   Stores > Configuration > Moogento > TrackEasy > Design: Tracking Pages

2. Set the layout options:
   - **Tracking page: URL prefix** - choose the storefront path segment for tracking links: `/track` (default), `/trackeasy`, or `/t`. Changing this only affects newly rendered links; links already sent in emails or SMS keep working regardless of this setting
   - **Standalone tracking page: Show website header & footer?** = No for a minimal, focused page (default); Yes to include your theme's header and navigation
   - **Standalone tracking page: Show QR top-right?** = Yes to display a QR code linking back to the tracking page (useful when page is printed; hidden on mobile)
   - **Include: Purchase Order ID on tracking page?** = Yes to show the PO number below the order ID (B2B stores; Growth and Pro plans only)
   - **Shipping address: Hide this 'country name'** - select your primary shipping country to simplify the displayed address

3. Under **Add: Contact Info Block**:
   - **Contact info block: Enable?** = Yes
   - **Contact info block: Content** - enter HTML; use `{{contact_us_url}}` and `{{support_email}}` as placeholders

4. Under **Add: Upsell/Custom Block**:
   - **Enable** = Yes (default) to show product recommendations below the timeline
   - **Add to: Standalone track/timeline pages** = Yes
   - **Add to: Frontend account single-order pages** = Yes to also show the block on customer account order detail pages
   - **Block: Type** - choose Cross-sell block, CMS Block, or raw HTML
   - For the cross-sell block, set: number of products, category filter, **Crossell block: Filter-in by Product attribute**, minimum price filter, and whether to fill empty slots with random products

   ![Crossell block product attribute filter with a dropdown Value cell](images/config-crossell-attribute-filter.png)

   The attribute filter's Value cell is attribute-aware:
   - Choosing a dropdown, multiple-select, or Yes/No attribute turns the Value box into a dropdown listing that attribute's real option labels - no need to type option text by hand.
   - Choosing a text-like attribute (text, textarea, price, decimal, date, or weight) keeps a plain text box, with a type hint and an example value shown underneath (for example, a price attribute shows a hint like "e.g. 24.99").
   - Media and image attributes do not appear in the attribute picker at all.
   - Values are matched by option label. If an option referenced by a saved filter row is later deleted from the attribute, that row shows "Current: {value} (no longer an option)" instead of silently disappearing, so you can update or remove it deliberately. A row whose attribute itself was removed shows "Current: {attribute} (no longer available)" in the Attribute column.

5. To customise the look, paste CSS into **Standalone tracking page: Custom CSS**.

6. Save Config and run `php bin/magento cache:clean`.

### Notes

- Tracking page URLs are token-authenticated. Each order gets a unique `moo_trackeasy_code` - the token is refreshed by cron every 5 minutes for new orders. Customers cannot guess another order's URL.
- The ordered items block can show or hide SKUs (`moogento_trackeasy/moo/items_show_sku`) and product names (`moogento_trackeasy/moo/items_show_name`).
- **Crossell block: Filter-in by Product attribute** (`moogento_trackeasy/moo/crossell_attribute_filter`) is only visible when the Block: Type is set to Cross-sell block and the upsell block is enabled.

---

## Other pages in this guide

- [TrackEasy overview, installation and FAQs](/docs/trackeasy)
- [TrackEasy: Delivery Emails, SMS and Timeline Setup](/docs/trackeasy-emails-and-sms)
- [TrackEasy: Reference, Tips and Troubleshooting](/docs/trackeasy-reference-and-troubleshooting)

<!-- docs-split: part-of="trackeasy" -->
