I am working on integrating with Hotelbeds API, but I have a problem with the authentication they require to send both the API Key and the X-Signature, a SHA256 hash in Hex format calculated from the API key, the secret plus current timestamps in seconds here is their example:
#!/bin/bash
apiKey="yourApiKey"
secret="yourSecret"
curl -i \
-X GET \
-H 'Accept:application/json' \
-H 'Api-key:'$apiKey'' \
-H 'X-Signature:'$(echo -n ${apiKey}${secret}$(date +%s)|sha256sum|awk '{ print $1}')'' \
https://api.test.hotelbeds.com/hotel-api/1.0/status
and this one also
//Begin UTC creation
var utcDate = Math.floor(new Date().getTime() / 1000);
//Begin Signature Assembly
var publicKey = environment["Api-key"];
var privateKey = environment["secret"];
var assemble = (publicKey+privateKey+utcDate);
//Begin SHA-256 Encryption
hash = CryptoJS.SHA256(assemble).toString();
encryption = (hash.toString(CryptoJS.enc.Hex));
postman.setEnvironmentVariable("X-Signature", encryption);
so I am using Laravel to have the authentication and here is my code:
$client = new \GuzzleHttp\Client();
$apiKey = "apiXXXXXXX";
$secret = "seceretXXXXX";
$assemble = $apiKey . $secret . Carbon::now()->timestamp;
// $hash = Hash::make($assemble);
$hash = base64_encode(hash('sha512', $assemble));
$headers = [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'Api-key' => $apiKey,
'X-Signature' => $$hash,
];
$apiURL = 'https://api.test.hotelbeds.com/hotel-api/1.0/status';
$res = $client->request('GET', $apiURL, [
'headers' => $headers,
'json' => [
"data" => [
"type" => "flight-offers-pricing",
]
],
]);
$statusCode = $res->getStatusCode();
$responseBody = json_decode($res->getBody(), true);
dd($responseBody);
but I get the following error Client error: GET https://api.test.hotelbeds.com/hotel-api/1.0/status
resulted in a `400 Bad Request
so how do send the API Key and the X-Signature, a SHA256 hash in Hex format calculated from the API key, the secret plus current timestamps in seconds
solved the problem and here is the new code
$client = new \GuzzleHttp\Client();
$apiKey = "apixxxxxx";
$secret = "secxxxxxx";
// Signature is generated by SHA256 (Api-Key + Shared Secret + Timestamp (in seconds))
$signature = hash("sha256", $apiKey . $secret . time());
$headers = [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'Api-key' => $apiKey,
'X-Signature' => $signature,
];
$apiURL = 'https://api.test.hotelbeds.com/hotel-api/1.0/status';
$res = $client->request('GET', $apiURL, [
'headers' => $headers,
]);
$statusCode = $res->getStatusCode();
$responseBody = json_decode($res->getBody(), true);
return $responseBody;
Based on this answer HotelBeds Php API providing me empty result it seems that you don't need to do anything extra and can just do the following. No need to add base64 on top of it
$apiKey = "apiXXXXXXX";
$secret = "seceretXXXXX";
$assemble = $apiKey . $secret . Carbon::now()->timestamp;
// $hash = Hash::make($assemble);
// $hash = base64_encode(hash('sha512', $assemble));
$hash = hash("sha256", $apiKey.$secret.time()); // <-- here
//...
not quite sure why do you use sha512 in php?