Reputation: 414
I am trying to call a shiplogic API (based in AWS), but I get 400 Bad Request
error.
I have tried various ways to request response from the AWS API such as S3, I have tried creating my own signature for a cURL request, and now I am trying this code.
$host = "api.shiplogic.com";
$accessKey = 'AKIA55D****';
$secretKey = 'cx0WDJLNj1Bmn2**';
$requestUrl = 'https://api.shiplogic.com';
$uri = '/tracking/shipments';
$httpRequestMethod = 'GET';
$data = '{"tracking_reference": "M3RPH"}';
require 'AWS/aws-autoloader.php';;
use Aws\Signature\SignatureV4;
use Aws\Credentials\Credentials;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
use Psr\Http\Client\ClientInterface;
$signature = new SignatureV4('execute-api', 'af-south-1');
$credentials = new Credentials($accessKey, $secretKey);
$psr7Request = new Request($httpRequestMethod, $requestUrl.$uri, ["content-type"=>"application/json"], $data);
$client = new Client([$requestUrl, 'timeout' => 30]);
$sr = $signature->signRequest($psr7Request, $credentials);
$response = $client->send($sr);
var_dump($response);
The short error is: PHP Fatal error: Uncaught GuzzleHttp\Exception\ClientException: Client error: GET https://api.shiplogic.com/tracking/shipments resulted in a 400 Bad Request response: Invalid or incomplete input
The full error is:
PHP Fatal error: Uncaught GuzzleHttp\Exception\ClientException: Client error: `GET https://api.shiplogic.com/tracking/shipments` resulted in a `400 Bad Request` response:
Invalid or incomplete input
in /home/path/myurl.com/path/AWS/GuzzleHttp/Exception/RequestException.php:113
Stack trace:
#0 /home/path/myurl.com/path/AWS/GuzzleHttp/Middleware.php(65): GuzzleHttp\Exception\RequestException::create()
#1 /home/path/myurl.com/path/AWS/GuzzleHttp/Promise/Promise.php(204): GuzzleHttp\Middleware::GuzzleHttp\{closure}()
#2 /home/path/myurl.com/path/AWS/GuzzleHttp/Promise/Promise.php(153): GuzzleHttp\Promise\Promise::callHandler()
#3 /home/path/myurl.com/path/AWS/GuzzleHttp/Promise/TaskQueue.php(48): GuzzleHttp\Promise\Promise::GuzzleHttp\Promise\{closure}()
#4 /home/path/myurl.com/path/AWS/GuzzleHttp/Promise/Promise.php(248): GuzzleHttp\Promise\TaskQueue->run()
#5 /home/path/myurl.com/path/AWS/GuzzleHttp/Promise/Promise.php(224): GuzzleHttp\Promise\Promise->invokeWaitFn()
#6 /home/path/myurl.com/path/AWS/GuzzleHttp/Promise/Promise.php(269): GuzzleHttp\Promise\Promise->waitIfPending()
#7 /home/path/myurl.com/path/AWS/GuzzleHttp/Promise/Promise.php(226): GuzzleHttp\Promise\Promise->invokeWaitList()
#8 /home/path/myurl.com/path/AWS/GuzzleHttp/Promise/Promise.php(62): GuzzleHttp\Promise\Promise->waitIfPending()
#9 /home/path/myurl.com/path/AWS/GuzzleHttp/Client.php(129): GuzzleHttp\Promise\Promise->wait()
#10 /home/path/myurl.com/path/apiSign.php(22): GuzzleHttp\Client->send()
#11 {main}
thrown in /home/path/myurl.com/path/AWS/GuzzleHttp/Exception/RequestException.php on line 113
EDIT:
Screenshot of cURL created by Postman
EDIT 2
Response from using $psr7Request = new Request($httpRequestMethod, $requestUrl.$uri.'?tracking_reference=M3RPH');
GuzzleHttp\Psr7\Response Object
(
[reasonPhrase:GuzzleHttp\Psr7\Response:private] => OK
[statusCode:GuzzleHttp\Psr7\Response:private] => 200
[headers:GuzzleHttp\Psr7\Response:private] => Array
(
[Date] => Array
(
[0] => Sat, 30 Jul 2022 09:08:57 GMT
)
[Content-Type] => Array
(
[0] => application/json
)
[Content-Length] => Array
(
[0] => 743
)
[Connection] => Array
(
[0] => keep-alive
)
[Ship-Logic-Request-Id] => Array
(
[0] => e78565f7-3a63-4831-8cdd-f4c720c13f06
)
[Apigw-Requestid] => Array
(
[0] => WEs-jjI6ifMEPcQ=
)
)
[headerNames:GuzzleHttp\Psr7\Response:private] => Array
(
[date] => Date
[content-type] => Content-Type
[content-length] => Content-Length
[connection] => Connection
[ship-logic-request-id] => Ship-Logic-Request-Id
[apigw-requestid] => Apigw-Requestid
)
[protocol:GuzzleHttp\Psr7\Response:private] => 1.1
[stream:GuzzleHttp\Psr7\Response:private] => GuzzleHttp\Psr7\Stream Object
(
[stream:GuzzleHttp\Psr7\Stream:private] => Resource id #45
[size:GuzzleHttp\Psr7\Stream:private] =>
[seekable:GuzzleHttp\Psr7\Stream:private] => 1
[readable:GuzzleHttp\Psr7\Stream:private] => 1
[writable:GuzzleHttp\Psr7\Stream:private] => 1
[uri:GuzzleHttp\Psr7\Stream:private] => php://temp
[customMetadata:GuzzleHttp\Psr7\Stream:private] => Array
(
)
)
)
POSTMAN response from the same call:
{
"shipments": [
{
"provider_id": 10,
"shipment_id": 14135,
"short_tracking_reference": "G9G",
"status": "cancelled",
"shipment_time_created": "2021-05-21T12:12:03.365338Z",
"shipment_time_modified": "2022-05-31T14:00:34.375688Z",
"shipment_collected_date": null,
"shipment_delivered_date": null,
"collection_from": "uAfrica.com",
"delivery_to": "",
"collection_hub": "Gauteng",
"delivery_hub": "Gauteng",
"service_level_code": "ECO",
"tracking_events": [
{
"id": 1940829,
"parcel_id": 0,
"date": "2021-11-22T14:21:00.000529Z",
"status": "delivered",
"source": "corneladmin",
"message": ""
},
{
"id": 1940828,
"parcel_id": 0,
"date": "2021-11-22T14:20:59.925068Z",
"status": "collected",
"source": "corneladmin",
"message": ""
},
{
"id": 1940812,
"parcel_id": 0,
"date": "2021-11-22T14:20:45.323472Z",
"status": "delivered",
"source": "corneladmin",
"message": ""
},
{
"id": 1940811,
"parcel_id": 0,
"date": "2021-11-22T14:20:45.317556Z",
"status": "collected",
"source": "corneladmin",
"message": ""
},
{
"id": 1940755,
"parcel_id": 0,
"date": "2021-11-22T14:19:12.481537Z",
"status": "delivered",
"source": "corneladmin",
"message": ""
},
{
"id": 1940754,
"parcel_id": 0,
"date": "2021-11-22T14:19:12.462331Z",
"status": "collected",
"source": "corneladmin",
"message": ""
},
{
"id": 1940726,
"parcel_id": 0,
"date": "2021-11-22T14:18:37.02554Z",
"status": "delivered",
"source": "sandbox-admin",
"lat": -25.806655,
"lng": 28.334732,
"message": "POD files captured"
},
{
"id": 1940725,
"parcel_id": 0,
"date": "2021-11-22T14:18:37.011858Z",
"status": "collected",
"source": "sandbox-admin",
"message": ""
},
{
"id": 1940713,
"parcel_id": 0,
"date": "2021-11-22T14:18:20.002241Z",
"status": "delivered",
"source": "sandbox-admin",
"lat": -25.806655,
"lng": 28.334732,
"message": "POD files captured"
},
{
"id": 1940712,
"parcel_id": 0,
"date": "2021-11-22T14:18:19.995663Z",
"status": "collected",
"source": "sandbox-admin",
"message": ""
},
{
"id": 332828,
"parcel_id": 0,
"date": "2021-06-04T09:30:36.170053Z",
"status": "cancelled",
"source": "sandbox-admin",
"message": ""
},
{
"id": 254076,
"parcel_id": 0,
"date": "2021-05-21T12:12:03.846219Z",
"status": "submitted",
"source": "sandbox-admin",
"message": ""
}
]
}
]
}
Upvotes: 1
Views: 3611
Reputation: 18027
The documentation says that
you need to pass the tracking_reference
parameter on the query string (just as you did with Postman):
https://api.shiplogic.com/tracking/shipments?tracking_reference=G9G
But that's not what your code does:
$data = '{"tracking_reference": "M3RPH"}';
$psr7Request = new Request($httpRequestMethod, $requestUrl.$uri, ["content-type"=>"application/json"], $data)
The exception message clearly shows that the parameter is missing from the URL:
`GET https://api.shiplogic.com/tracking/shipments` resulted in a `400 Bad Request` response
You should do something like this instead:
$psr7Request = new Request($httpRequestMethod, $requestUrl.$uri.'?tracking_reference=M3RPH');
Upvotes: 6
Reputation: 86
I was facing the same issue while using Creatio API. Just like your case the API was working in Postman but not when using Curl in PHP.
Sometimes postman sends some extra headers in the HTTP request. In my case postman was sending a cookie
header anonymously. So to check this: Navigate to the code section of Postman which appears on the right side of the application. Choose PHP as a programming language, it will show you the complete Curl
request for your case.
Hope this helps!
Upvotes: 0