Add "native" FedEx tracking
parent
02a9646964
commit
ac5ac2da00
@ -0,0 +1,187 @@
|
||||
<?php
|
||||
|
||||
class Tracking_FedEx {
|
||||
|
||||
public static function getAuthToken() {
|
||||
$headers = [
|
||||
'Content-Type' => 'application/x-www-form-urlencoded'
|
||||
];
|
||||
|
||||
$postdata = http_build_query([
|
||||
"grant_type" => "client_credentials",
|
||||
"client_id" => env("fedex_apikey", ""),
|
||||
"client_secret" => env("fedex_secret", "")
|
||||
]);
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 45);
|
||||
//curl_setopt($ch, CURLOPT_URL, "https://apis-sandbox.fedex.com/oauth/token"); // TEST
|
||||
curl_setopt($ch, CURLOPT_URL, "https://apis.fedex.com/oauth/token"); // PROD
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
|
||||
$response = curl_exec($ch);
|
||||
|
||||
$data = json_decode($response, true);
|
||||
|
||||
if (isset($data["access_token"])) {
|
||||
return [$data["access_token"], $data["expires_in"]];
|
||||
}
|
||||
throw new Exception("Couldn't get FedEx access token.");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $code
|
||||
* @return \TrackingInfo
|
||||
* @throws TrackingException
|
||||
*/
|
||||
public static function track(string $code, string $carrier = ""): TrackingInfo {
|
||||
global $memcache;
|
||||
$barcode = new TrackingBarcode($code);
|
||||
|
||||
$fedexauthtoken = $memcache->get("logistics.tracking.fedex_auth_token");
|
||||
if ($fedexauthtoken == false) {
|
||||
$tokendata = Tracking_FedEx::getAuthToken();
|
||||
$memcache->set("logistics.tracking.fedex_auth_token", $tokendata[0], $tokendata[1] - 120);
|
||||
$fedexauthtoken = $tokendata[0];
|
||||
}
|
||||
|
||||
try {
|
||||
$trackrequest = [
|
||||
"includeDetailedScans" => true,
|
||||
"trackingInfo" => [
|
||||
[
|
||||
//"shipDateBegin" => date("Y-m-d", strtotime("now - 3 months")),
|
||||
"trackingNumberInfo" => [
|
||||
"trackingNumber" => $barcode->getCode()
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
$headers = [
|
||||
"Authorization: Bearer $fedexauthtoken",
|
||||
'X-locale: en_US',
|
||||
'Content-Type: application/json'
|
||||
];
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 45);
|
||||
//curl_setopt($ch, CURLOPT_URL, "https://apis-sandbox.fedex.com/track/v1/trackingnumbers"); // TEST
|
||||
curl_setopt($ch, CURLOPT_URL, "https://apis.fedex.com/track/v1/trackingnumbers"); // PROD
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($trackrequest));
|
||||
curl_setopt($ch, CURLOPT_ENCODING, "");
|
||||
$response = curl_exec($ch);
|
||||
|
||||
// CHECK TO SEE IF WE GOT AN ERROR
|
||||
if ((curl_errno($ch)) && (curl_errno($ch) != 0)) {
|
||||
throw new TrackingException(curl_error($ch));
|
||||
}
|
||||
|
||||
$result = json_decode($response, true);
|
||||
|
||||
if (isset($result["errors"]) || !empty($result["errors"])) {
|
||||
if (count($result["errors"]) > 0) {
|
||||
throw new TrackingException($result["errors"][0]["message"]);
|
||||
}
|
||||
throw new TrackingException("The FedEx tracking system responded with an error. Try again later.");
|
||||
}
|
||||
|
||||
if (!empty($result["output"]["completeTrackResults"]) && !empty($result["output"]["completeTrackResults"][0]["trackResults"])) {
|
||||
$trackinfo = $result["output"]["completeTrackResults"][0]["trackResults"][0];
|
||||
} else {
|
||||
throw new TrackingException("No tracking details found.");
|
||||
}
|
||||
if (!empty($result["output"]["completeTrackResults"][0]["trackResults"][0]["error"])) {
|
||||
throw new TrackingException($result["output"]["completeTrackResults"][0]["trackResults"][0]["error"]["message"]);
|
||||
}
|
||||
} catch (TrackingException $ex) {
|
||||
throw $ex;
|
||||
} catch (Exception $ex) {
|
||||
throw new TrackingException("There was a server problem. This code cannot be tracked right now.");
|
||||
}
|
||||
|
||||
$info = new TrackingInfo();
|
||||
|
||||
$info->setCode($trackinfo["trackingNumberInfo"]["trackingNumber"]);
|
||||
|
||||
$info->setCarrier("fedex");
|
||||
$info->setService(new Service($trackinfo["serviceDetail"]["type"], $trackinfo["serviceDetail"]["description"]));
|
||||
|
||||
// Set carrier info: Ground, Express, Freight, etc
|
||||
$carrierid = "fedex";
|
||||
switch ($trackinfo["trackingNumberInfo"]["carrierCode"]) {
|
||||
case "FEDEX_GROUND":
|
||||
case "FEDEX_EXPRESS":
|
||||
case "FEDEX_FREIGHT":
|
||||
default:
|
||||
$carrierid = "fedex";
|
||||
break;
|
||||
}
|
||||
$info->setCarrierAttributionText(CarrierAssets::getAttribution(Carriers::getCarrierCode($carrierid)));
|
||||
$info->setCarrierLogo(CarrierAssets::getLogo(Carriers::getCarrierCode($carrierid)));
|
||||
|
||||
if (count($trackinfo["scanEvents"]) > 0) {
|
||||
$current = $trackinfo["scanEvents"][0];
|
||||
$current_status = new TrackingEntry(
|
||||
TrackingStatus::FedExEventTypeToStatus($current["eventType"]),
|
||||
($current["eventDescription"] ?? "Unknown")
|
||||
. (TrackingStatus::FedExEventTypeToStatus($current["eventType"]) == TrackingStatus::TRACKING_STATUS_UNKNOWN ? " " . $current["eventType"] : ""),
|
||||
date("c", strtotime($current["date"]))
|
||||
);
|
||||
|
||||
$current_location = new Location();
|
||||
// FedEx docs say it should be $current["scanLocation"]["locationContactAndAddress"]["address"]["...}] but it's not I guess
|
||||
$current_location->city = $current["scanLocation"]["city"] ?? "";
|
||||
$current_location->state = $current["scanLocation"]["stateOrProvinceCode"] ?? "";
|
||||
$current_location->zip = $current["scanLocation"]["postalCode"] ?? "";
|
||||
$current_location->country = $current["scanLocation"]["countryCode"] ?? "";
|
||||
$current_status->setLocation($current_location);
|
||||
|
||||
$info->setCurrentStatus($current_status);
|
||||
}
|
||||
|
||||
|
||||
$to = new Location();
|
||||
$to->city = $trackinfo["recipientInformation"]["address"]["city"] ?? "";
|
||||
$to->state = $trackinfo["recipientInformation"]["address"]["stateOrProvinceCode"] ?? "";
|
||||
$to->zip = $trackinfo["recipientInformation"]["address"]["postalCode"] ?? "";
|
||||
$to->country = $trackinfo["recipientInformation"]["address"]["countryCode"] ?? "";
|
||||
$info->setTo($to);
|
||||
|
||||
$from = new Location();
|
||||
$from->city = $trackinfo["shipperInformation"]["address"]["city"] ?? "";
|
||||
$from->state = $trackinfo["shipperInformation"]["address"]["stateOrProvinceCode"] ?? "";
|
||||
$from->zip = $trackinfo["shipperInformation"]["address"]["postalCode"] ?? "";
|
||||
$from->country = $trackinfo["shipperInformation"]["address"]["countryCode"] ?? "";
|
||||
$info->setFrom($from);
|
||||
|
||||
foreach ($trackinfo["scanEvents"] as $history) {
|
||||
$location = new Location();
|
||||
$location->city = $history["scanLocation"]["city"] ?? "";
|
||||
$location->state = $history["scanLocation"]["stateOrProvinceCode"] ?? "";
|
||||
$location->zip = $history["scanLocation"]["postalCode"] ?? "";
|
||||
$location->country = $history["scanLocation"]["countryCode"] ?? "";
|
||||
if (!empty($history["date"])) {
|
||||
$datetimestring = date("c", strtotime($history["date"]));
|
||||
} else {
|
||||
$datetimestring = "";
|
||||
}
|
||||
$info->appendHistoryEntry(new TrackingEntry(
|
||||
TrackingStatus::FedExEventTypeToStatus($history["eventType"]),
|
||||
($history["eventDescription"] ?? "Unknown")
|
||||
. (TrackingStatus::FedExEventTypeToStatus($history["eventType"]) == TrackingStatus::TRACKING_STATUS_UNKNOWN ? " " . $history["eventType"] : ""),
|
||||
$datetimestring,
|
||||
$location));
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue