FedEx is going to migrate to oAuth2 API for their Web Services in 2024 and I'm trying to change our shipping library to work with it. I was able to Authenticate - which is great and getting bearer token. Now I'm trying to get Rates and Transit Times. I'm using PHP. This is my script for the API call:
$token = $this->get_token();
$headers = [
'Content-Type: application/json',
'Authorization: Bearer '.$token,
'X-locale: en_US'
];
$url = "https://apis.fedex.com/rate/v1/rates/quotes";
$payload = [];
$payload["accountNumber"] = [
"value" => "XXXXXXXXX"
];
$payload["requestedShipment"] = [];
$payload["requestedShipment"]["shipper"]["address"] = [
"postalCode" => "L4Z1X3",
"countryCode" => "CA"
];
$payload["requestedShipment"]["recipient"]["address"] = [
"postalCode" => "V1Y5E1",
"countryCode" => "CA"
];
$payload["requestedShipment"]["pickupType"] = "CONTACT_FEDEX_TO_SCHEDULE";
$payload["requestedShipment"]["requestedPackageLineItems"][0] = [
"weight" => [
"units" => "KG",
"value" => "10"
]
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // Added this on local system to avoid SSL error
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // Added this on local system to avoid SSL error
curl_setopt($ch, CURLOPT_ENCODING, "gzip"); // Added this to decode the response
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$output = curl_exec($ch);
$http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$content_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
$curlerr = curl_error($ch);
curl_close($ch);
// TO DEBUG OUTPUT
echo "OUTPUT: ".$output."<br><br>";
echo "HTTP STATUS: ".$http_status."<br><br>";
echo "CONTENT TYPE: ".$content_type."<br><br>";
echo "ERROR: ".$curlerr."<br><br>";
The response that I'm getting:
OUTPUT: {"transactionId":"874d6e61-d390-4410-a949-76d11e2ae67a","errors":[{"code":"INVALID.INPUT.EXCEPTION","message":"Invalid field value in the input"}]}
HTTP STATUS: 422
CONTENT TYPE: application/json
ERROR:
I have a feeling that my JSON formatting may not be correct or missing something. I tried addslashes(json_encode($payload)) - it returns the same thing. I checked curl documentation for maybe any option that I'm missing - can't see what I can add to make it work.
Any suggestions are appreciated.
So, after trial and error I figured out the solution for my problem. If anybody faces the same issue this is what worked for me:
Below is the working code. My development environment is on Windows 11 (WAMP).