Answer "where is my order?" from one support console
Your team types a customer email, name, or tracking number and gets every shipment, its live status, and a ready-to-send update email.
Build me an internal app my support team opens every time a customer asks where their order is. It is a staffed console for tickets that need a human, not an auto-responder. The person using it is a support rep with a customer on chat or email right now, so every screen should get them to an answer in as few clicks as possible.
The main screen is one search box and nothing else until a search runs. The box accepts three kinds of input and the handler decides which it got: a customer email address, a customer name, or a raw tracking number. Treat input that looks like an email as an email search, input that is mostly digits or a courier-style alphanumeric code as a tracking number, and anything else as a name search. Let the rep override the detected mode with a small selector next to the box in case a customer name looks like a tracking code.
Email and name searches run against Shopify. Call Shopify Search Customers with the query, then for each matching customer call Get Customer Orders, then for each order call List Fulfillments for Order to pull every fulfillment and its tracking number. If Search Customers returns more than one person, show a short disambiguation list with name, email, and order count so the rep picks the right customer before the shipment list loads. Collect the tracking numbers from the fulfillments and look them up in AfterShip with List Trackings using the tracking number as the keyword filter, so each Shopify fulfillment is joined to its live AfterShip tracking.
A tracking number search skips Shopify entirely and goes straight to AfterShip List Trackings with the number as the keyword filter, then opens the matching shipment directly if there is exactly one result.
Search results render as a list of shipment cards, one per fulfillment or tracking. Each card shows the order number, the courier, the current status, the last checkpoint and when it happened, and the expected delivery date. Sort a customer's shipments newest first so the order they are most likely calling about sits at the top. Flag any shipment whose most recent checkpoint is more than 72 hours old in red with a short label such as No movement for 4 days, and make that threshold easy to change in one place.
Selecting a shipment opens a detail panel built from AfterShip Get Tracking by ID. Address the tracking by its AfterShip id, which comes back on the list and create calls. Never try to fetch a tracking by slug or tracking number in the path, because that is not how the API is addressed. The panel shows the full checkpoint timeline in reverse chronological order with each checkpoint's message, location, and timestamp, plus the current status, the courier name, the origin and destination, and the expected delivery date. Note that every AfterShip response is wrapped in a meta and data envelope, so read the payload from data.tracking or data.trackings rather than the top level.
Handle the case where a Shopify fulfillment has a tracking number that was never registered in AfterShip. When the keyword lookup returns nothing for a tracking number, call Detect Courier to work out which couriers match the number's format, then call Create Tracking to register it and load the timeline from the newly returned id. Omitting the courier slug on create lets AfterShip auto-detect, but some couriers additionally require a tracking account number, a tracking key, a ship date, or a destination postal code, and creation fails without them. When create fails for a missing field, show the rep a plain-language message naming what is missing and offer a small form to supply it and retry, rather than a raw API error.
AfterShip is rate limited to ten requests per second, so batch the per-order and per-fulfillment lookups instead of firing one request per row in a loop, and throttle so a customer with dozens of orders does not trip a 429. Show a loading state on the shipment list while lookups are still resolving.
Every detail panel has a Send update button. It composes a plain-language status email to the customer, prefilled from the latest checkpoint: what the current status means in ordinary words, where the parcel was last seen, and when it is expected to arrive. The subject and body are fully editable in the panel before anything goes out, and nothing sends until the rep clicks send. Sending uses Gmail Send a Message to the customer's email address from the Shopify customer record, or a field the rep fills in when the search started from a bare tracking number. When a shipment has been sitting still for over 72 hours, the prefilled draft should acknowledge the delay rather than cheerfully restating the last scan.
Keep a per-user log of which customers each rep has already emailed today, stored in the app so it survives reloads. Record the rep, the customer email, the shipment, and the timestamp on every send. Before a rep sends, check the log across all reps for that customer today and show a clear warning if someone has already emailed them, naming who and when, with the option to send anyway. Add a small Sent today panel listing that rep's own sends so they can see their own history at a glance.
What does this prompt do?
- One search box handles all three ways a rep starts: a customer email address, a customer name, or a raw tracking number pasted straight from the customer's message.
- Pulls the customer's orders and shipments from your Shopify store, matches each one to its live AfterShip tracking, and lists them newest first so the most recent order is always on top.
- Opens any shipment to a full delivery timeline: every scan and checkpoint, the current status, the courier, and the expected delivery date. Shipments with no movement in over 72 hours are flagged in red.
- One Send update button writes a plain-language status email to the customer, prefilled from the latest checkpoint and fully editable before it goes out through Gmail.
- Keeps a per-rep log of who has already been emailed today, so two people on the same queue never double-message the same customer.
What do I need to use this?
- An AfterShip account where your shipments are tracked
- A Shopify store login with access to customers and orders
- A Gmail account your team sends customer updates from
- A few minutes to confirm the reply-from address your reps should use
How can I customize it?
- Change the stale-shipment threshold from 72 hours to whatever your couriers make normal, for example 48 hours for domestic-only shipping
- Rewrite the default email template so the tone and sign-off match your brand voice
- Adjust how many recent orders load per customer, or filter out orders older than a certain date
- Decide whether the already-emailed log resets daily or holds for a longer window
FAQs
Do reps still need to open Shopify and the tracking site separately?
What if the customer only gives us a tracking number and nothing else?
What happens if a shipment was never registered for tracking?
How does it stop two reps emailing the same customer?
Can reps edit the email before it goes out?
Will this work if we ship with several different couriers?
Related templates
Pick a repricing rule, send an assistant out to check competitor pages, then approve the new prices that clear your margin floor.
A calibration board that lines up every candidate's answer to the same question, hides names until your panel has scored, and writes the agreed rating back.
Search three months of global coverage on your topic, rank the outlets actually writing about it, and draft a tailored pitch for each one.
Open one board every morning to see every outstanding quote by age and value, decide on each one, and send follow-ups only after you approve them.
See every HoneyBook project's booked revenue next to what actually landed in your bank, chase what is late, and bill the next payment in one click.
Paste a customer email or license key and see every purchase, license, and membership in one place, then refund or reset a key right from the row.
Stop tabbing between your store and your tracking tool.
Give your support team one screen that answers "where is my order?" and sends the customer a clear update in the same click.