A shipping plugin may store a tracking number and a link without retrieving a carrier event timeline. Trace supplies a separate tracking layer: your server reads the parcel information, calls the API, and renders an authorized view inside the store.
The exact tracking-number field depends on your WooCommerce extension. Trace does not ship a ready-made WooCommerce plugin, create shipping labels or automatically discover your order metadata.
Start with the tracking data your shipping extension actually stores
Identify the component that creates labels or writes shipment tracking information. The WooCommerce Shipment Tracking extension has its own REST resources; other plugins may use different metadata or APIs. Use the extension’s supported interface rather than assuming one universal order-meta key.
Keep the tracking-item identifier, carrier number and WooCommerce order ID as separate values. The official Shipment Tracking extension distinguishes tracking_id from tracking_number. Preserving that distinction lets you update or remove an item without treating a parcel number as an order resource identifier.
| Store workflow | Integration example | Important distinction |
|---|---|---|
| Merchant adds a tracking item | Read the extension’s order tracking items | A tracking link is not a verified carrier timeline. |
| Two boxes for one order | Create two Trace shipment records with one order_id | Show each parcel’s state before summarizing the order. |
| Guest checkout | Authorize a limited tracking-page request on your server | An order number alone should not expose another buyer’s shipment. |
Keep network work outside the storefront request
Call Trace from a server-side plugin job or service. Do not ship your API key to the browser or block every product-page request on a live carrier lookup. A live lookup can take up to roughly 90 seconds; your storefront should read a local projection or queue work when data needs refreshing.
Use POST /v1/shipments for an order-linked record when you need ongoing monitoring. Use POST /v1/track for a direct lookup when your application controls refreshes. For WordPress order storage, use WooCommerce’s supported order access APIs so the integration does not depend on a particular database-table layout.
- Store credentials in server configuration and restrict your backend endpoint to the correct customer or staff role.
- Use a stable idempotency key for each order-parcel cycle, then save the returned shipment ID.
- Verify raw webhook bytes before parsing JSON, and deduplicate the verified event_id before updating order notes or notifications.
- Keep carrier delivery state separate from the payment and fulfillment decisions in your store.
Example: handle a direct tracking lookup in PHP
This standalone server-side cURL example can be adapted to a trusted WordPress job. It checks transport errors and HTTP status before treating the response as tracking data. Replace the environment values with your own secure configuration; use WooCommerce APIs to read the authorized order’s real number.
PHP · server-side lookup with explicit error handling
$number = getenv('TRACKING_NUMBER');
if (!$number) { throw new RuntimeException('Set TRACKING_NUMBER'); }
$ch = curl_init('https://api.traceapi.dev/v1/track');
curl_setopt_array($ch, [
CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 95,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('TRACE_API_KEY'),
'Content-Type: application/json'
],
CURLOPT_POSTFIELDS => json_encode([
'tracking_number' => $number, 'carrier' => 'ups'
], JSON_THROW_ON_ERROR)
]);
$raw = curl_exec($ch);
if ($raw === false) { $error = curl_error($ch); curl_close($ch);
throw new RuntimeException($error); }
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$body = json_decode($raw, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300) {
throw new RuntimeException($body['error']['message'] ?? 'Tracking failed');
}
// Persist only the fields needed by your authorized order view.
$lastChecked = $body['last_checked_at'];Give customers a useful status without overstating freshness
Render a concise status headline with the source description, parcel link and last_checked_at. If timestamp is null, display timestamp_local with ‘timezone not supplied.’ Do not construct a delivery date or move an offset-free scan into UTC.
During an outage, leave the last known status visible only if your application labels it appropriately. allow_stale is an explicit request option, not the default. It can return an eligible verified snapshot younger than 24 hours after a live source failure; it does not establish a new event or trigger new shipment notifications.
For example, an order with one delivered parcel and one customs parcel should explain both states. An order with a failed lookup should show ‘Tracking update unavailable’ rather than marking the customer’s purchase as failed.
Test the operational edges before enabling every order
Use staging orders and simulated sandbox responses to check delivered, exception and unknown-timezone states. Confirm that guest customers cannot enumerate other orders, that receiver redirects are avoided, and that your job scheduler will recover from a paused or failed refresh.
Track missing results, retry rates, receiver authentication failures and successful lookup usage. These measurements help you choose a sensible refresh interval. The Trace free plan allows 200 monthly lookups at 10 requests per minute; cache hits still count as lookups. Paid checkout remains disabled in the current release.
- Use small real carrier samples after the sandbox UI works.
- Test repeat jobs with the same Idempotency-Key; changed input should produce a conflict instead of a duplicate parcel.
- Check delivery-attempt handling and partial deliveries separately.
- Keep email sending and store-order mutations behind your own deduplicated business rules.
Common questions
Is there a standard WooCommerce tracking-number metadata key?
Do not assume one. Read the documented API or metadata contract of the shipping or tracking extension installed on the store.
Can I call Trace directly from a browser widget?
Use your own authenticated backend. A public widget would expose an account API key and could allow unauthorized tracking or quota consumption.
Does Trace replace WooCommerce label purchasing?
No. Keep your shipping-label provider and use Trace as a tracking-data layer when its supported-source behavior fits your parcels.
References & next steps
Implementation details were checked against Trace’s current API. External product details may change; verify the linked documentation before deciding.