Use PHP on the server to call Trace and return an authorized, minimal tracking view to your customer. The integration does not require a native plugin, but your application still owns order authorization, refresh policy and error presentation.
A cURL transport error and an API error are different. A timeout may mean no response reached you; a structured HTTP failure can explain authentication, quota or source availability. Preserve that distinction so your support team can investigate it.
Send JSON with a bounded timeout
The example requires the PHP cURL extension and an environment-provided key and tracking number. It uses a fixed API URL rather than a caller-supplied host, and does not follow redirects with the authorization header. Run it behind your own order authorization, not as an unrestricted public tracking proxy.
PHP · minimal server-side lookup
<?php
$key = getenv("TRACE_API_KEY");
$number = getenv("TRACKING_NUMBER");
if (!$key || !$number) throw new RuntimeException("Missing configuration");
$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_FOLLOWLOCATION => false,
CURLOPT_HTTPHEADER => ["Authorization: Bearer " . $key, "Content-Type: application/json"],
CURLOPT_POSTFIELDS => json_encode(["tracking_number" => $number], JSON_THROW_ON_ERROR),
]);
$raw = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($raw === false) { curl_close($ch); throw new RuntimeException("Tracking transport failed"); }
curl_close($ch);
$body = json_decode($raw, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300) {
throw new RuntimeException("Tracking API HTTP " . $status);
}
// Validate fields your view uses; do not return the entire response blindly.
echo htmlspecialchars($body["status"], ENT_QUOTES, "UTF-8");Choose a different response for each failure
A 401 requires fixing the server credential rather than asking the buyer to retry. A monthly quota response needs a plan or reset decision. A transient source failure can retain the last verified snapshot in your database with an explicit age label. Never claim a new carrier update when a request failed.
| Failure | Application action |
|---|---|
| Transport timeout | Record a correlation ID and offer a bounded later retry. |
| 401 authentication | Check server configuration; keep the key out of logs. |
| 402 monthly quota | Pause refreshes and inspect Billing. |
| 429 rate limit | Honor Retry-After and coordinate requests. |
| 503 source unavailable | Show temporary unavailability; do not invent a tracking status. |
Keep slow carrier work out of a busy PHP request pool
A 95-second client timeout does not extend your PHP execution limit, reverse proxy deadline or hosting request limit. Align all of those limits deliberately. For a page with many parcels, prefer a stored shipment snapshot or an asynchronous tracking job, and have a worker refresh it. One buyer reload should not fan out to dozens of carrier requests.
Validate escaping, empty fields and partial outages
Test a sandbox fixture before a live number. Escape all carrier descriptions and locations when rendering HTML, including text that looks harmless in a sample. Check null timestamps, missing locations and an empty estimate. Test a non-JSON upstream response as a failure so an HTML error page never becomes a successful shipment view.
Common questions
Does this install a WooCommerce extension?
No. This is a PHP server integration. A store still needs its own order lookup, access checks and fulfillment mapping; the WooCommerce guide covers those decisions.
References & next steps
Implementation details were checked against Trace’s current API. External product details may change; verify the linked documentation before deciding.