Notre API est conçue pour utiliser des URL prévisibles et orientées ressources, ainsi que des codes de réponse HTTP pour signaler les erreurs. Nous utilisons des fonctionnalités HTTP intégrées, telles que les verbes HTTP, compatibles avec tous les clients HTTP standard. Toutes les réponses de l'API, y compris les erreurs et les données, sont retournées uniquement au format JSON.
Flux de l'API
Le diagramme ci-dessous illustre les deux phases principales : le Catalog Management (navigation dans les catégories et les offres) et le Checkout Process (disponibilité, réservation, confirmation).
1. Configure ton environnement de test
1.1. Authentification
- L'authentification utilise de simples principes simples basés sur HMAC.
- Pour les requêtes de test, utilise ta clé PUBLIQUE. Tu peux trouver ta clé dans ton Tableau de bord Regiondo, sous Connectivité > Configuration de l'API > Générer les clés
1.2. Environnement Sandbox vs. environnement Live
- Les offres créées dans ton compte Regiondo Live n'apparaîtront pas dans l'environnement Sandbox et ne peuvent pas être récupérées via la clé publique.
- Pour tester ton implémentation API, tu auras besoin d'un compte Regiondo dans l'environnement Sandbox et de publier tes offres sur regiondo-dev-de.de
Important :
N'envoie jamais ta clé privée avec les appels API. Envoie uniquement la clé publique ouvertement, et utilise la clé privée de ton côté pour chiffrer et signer les requêtes.
2. Documentation
La documentation de l'API Regiondo et notre PDF téléchargeable couvrent tous les endpoints. En les consultant, assure-toi d'ouvrir les sections Response Sample et Response Schema pour comprendre la structure des données.
Note :
- Des exemples de code sont disponibles sur GitHub : https://github.com/regiondo-dev/api
- Lorsque tu utilises une URL de requête, supprime le préfixe
sandbox-et assure-toi qu'il n'y a pas d'espaces supplémentaires à la fin de l'URL.
3. Configuration de l'authentification
Pour te connecter à l'API Regiondo, tu dois suivre quelques étapes essentielles pour garantir une transmission des données sécurisée et précise. Ce guide t'accompagnera tout au long du processus et te signalera les problèmes courants pouvant entraîner une erreur 401 Non autorisé. Suis ces instructions attentivement pour éviter les erreurs fréquentes.
3.1. Headers
Chaque requête doit inclure les en-têtes suivants :
X-API-HASH: {{regiondoHmacAuthHeader}}
X-API-TIME: {{regiondoReqTime}}
X-API-ID: XXXXXXX3.2. Pre-request Script
Ce script génère le timestamp et le HMAC requis à partir de tes clés publique et secrète :
function getQueryString(url) {
var arrSplit = url.split('?');
return arrSplit.length 1 ? url.substring(url.indexOf('?') + 1) : '';
}
function getAuthHeader(requestUrl) {
var PUBLIC_KEY = 'XXXXXXX';
var SECRET_KEY = 'XXXXXXX';
var queryString = getQueryString(requestUrl);
var timestamp = Date.now();
pm.environment.set("regiondoReqTime", timestamp);
var requestData = timestamp + PUBLIC_KEY + queryString;
console.log("Message to be hashed with private key: " + requestData);
var hmacDigest = CryptoJS.enc.Hex.stringify(CryptoJS.HmacSHA256(requestData, SECRET_KEY));
var authHeader = hmacDigest;
return authHeader;
}
var hmac = getAuthHeader(request['url']);
console.log("HmacSHA256-Hash: " + hmac);
postman.setEnvironmentVariable('regiondoHmacAuthHeader', hmac);4. Problèmes fréquents entraînant des erreurs 401 Non autorisé
4.1. Mauvaise intégration des headers
Assure-toi que tes headers sont correctement intégrés dans tes requêtes. Vérifie que les noms et les valeurs des en-têtes correspondent à l'exemple fourni. Toute différence dans les noms ou les valeurs des en-têtes peut entraîner un échec de l'authentification.
4.2. Problèmes d'intégration de la clé sécurisée
Assure-toi que la clé sécurisée (SECRET_KEY) est correctement implémentée dans ton script de pré-requête. Toute erreur dans la clé sécurisée entraînera un échec du processus d'authentification. Vérifie que le script copie correctement la clé sécurisée et génère le digest HMAC.
4.3. Format de date incorrect
Le format de date dans tes requêtes doit suivre le bon encodage. Au lieu d'utiliser des virgules (,), tu dois les encoder en URL sous la forme %2C. Par exemple, les dates doivent être formatées comme suit :
2024-06-01%2C2024-07-01
5. Exemples de scripts de connexion
Les exemples suivants montrent comment se connecter à l'API Regiondo dans différents langages de programmation. Remplace toutes les valeurs fictives (par ex., XXXXXXX) par tes identifiants réels et une URL d'endpoint valide.
cURL
PUBLIC_KEY="XXXXXXX"
SECRET_KEY="XXXXXXX"
API_URL="https://api.regiondo.com/v1/..."
get_query_string() {
local url=$1
echo "${url#*\?}"
}
get_auth_header() {
local url=$1
local query_string=$(get_query_string "$url")
local timestamp=$(($(date +%s%N)/1000000))
local request_data="${timestamp}${PUBLIC_KEY}${query_string}"
local hmac_digest=$(echo -n "$request_data" | openssl dgst -sha256 -hmac "$SECRET_KEY" | sed 's/^.* //')
echo "$timestamp" "$hmac_digest"
}
read timestamp hmac <><(get_auth_header>
curl -X GET "$API_URL" \
-H "X-API-HASH: $hmac" \
-H "X-API-TIME: $timestamp" \
-H "X-API-ID: $PUBLIC_KEY"
PHP
define('PUBLIC_KEY', 'XXXXXXX');
define('SECRET_KEY', 'XXXXXXX');
define('API_URL', 'https://api.regiondo.com/v1/...');
function getQueryString($url) {
$parts = parse_url($url);
return isset($parts['query']) ? $parts['query'] : '';
}
function getAuthHeader($url) {
$queryString = getQueryString($url);
$timestamp = time() * 1000;
$requestData = $timestamp . PUBLIC_KEY . $queryString;
$hmacDigest = hash_hmac('sha256', $requestData, SECRET_KEY);
return [
'timestamp' = $timestamp,
'hmac' = $hmacDigest
];
}
$url = API_URL;
$authData = getAuthHeader($url);
$headers = [
'X-API-HASH: ' . $authData['hmac'],
'X-API-TIME: ' . $authData['timestamp'],
'X-API-ID: ' . PUBLIC_KEY
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
} else {
echo 'Response:' . $response;
}
curl_close($ch);
?
PHP (using AJAX)
define('PUBLIC_KEY', 'XXXXXXX');
define('SECRET_KEY', 'XXXXXXX');
function getQueryString($url) {
$parts = parse_url($url);
return isset($parts['query']) ? $parts['query'] : '';
}
function getAuthHeader($url) {
$queryString = getQueryString($url);
$timestamp = time() * 1000;
$requestData = $timestamp . PUBLIC_KEY . $queryString;
$hmacDigest = hash_hmac('sha256', $requestData, SECRET_KEY);
return [
'timestamp' = $timestamp,
'hmac' = $hmacDigest
];
}
$url = 'https://api.regiondo.com/v1/...';
$authData = getAuthHeader($url);
?
JavaScript/Node.ja
const crypto = require('crypto');
const axios = require('axios');
const PUBLIC_KEY = 'XXXXXXX';
const SECRET_KEY = 'XXXXXXX';
const API_URL = 'https://api.regiondo.com/v1/...';
function getQueryString(url) {
const urlObj = new URL(url);
return urlObj.search;
}
function getAuthHeader(url) {
const queryString = getQueryString(url);
const timestamp = Date.now();
const requestData = `${timestamp}${PUBLIC_KEY}${queryString}`;
const hmacDigest = crypto.createHmac('sha256', SECRET_KEY)
.update(requestData)
.digest('hex');
return {
timestamp: timestamp,
hmac: hmacDigest
};
}
const { timestamp, hmac } = getAuthHeader(API_URL);
axios.get(API_URL, {
headers: {
'X-API-HASH': hmac,
'X-API-TIME': timestamp,
'X-API-ID': PUBLIC_KEY
}
})
.then(response = console.log(response.data))
.catch(error = console.error('Error:', error));
Python
import time
import hmac
import hashlib
import requests
PUBLIC_KEY = 'XXXXXXX'
SECRET_KEY = 'XXXXXXX'
API_URL = 'https://api.regiondo.com/v1/...'
def get_query_string(url):
return url.split('?', 1)[1] if '?' in url else ''
def get_auth_header(url):
query_string = get_query_string(url)
timestamp = int(time.time() * 1000)
request_data = f"{timestamp}{PUBLIC_KEY}{query_string}"
hmac_digest = hmac.new(SECRET_KEY.encode(), request_data.encode(), hashlib.sha256).hexdigest()
return {
'timestamp': timestamp,
'hmac': hmac_digest
}
auth_data = get_auth_header(API_URL)
headers = {
'X-API-HASH': auth_data['hmac'],
'X-API-TIME': str(auth_data['timestamp']),
'X-API-ID': PUBLIC_KEY
}
response = requests.get(API_URL, headers=headers)
print(response.text)Ruby
require 'uri'
require 'net/http'
require 'openssl'
require 'time'
PUBLIC_KEY = 'XXXXXXX'
SECRET_KEY = 'XXXXXXX'
API_URL = 'https://api.regiondo.com/v1/...'
def get_query_string(url)
uri = URI(url)
uri.query
end
def get_auth_header(url)
query_string = get_query_string(url) || ''
timestamp = (Time.now.to_f * 1000).to_i
request_data = "#{timestamp}#{PUBLIC_KEY}#{query_string}"
hmac_digest = OpenSSL::HMAC.hexdigest('sha256', SECRET_KEY, request_data)
{ timestamp: timestamp, hmac: hmac_digest }
end
auth_data = get_auth_header(API_URL)
uri = URI(API_URL)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['X-API-HASH'] = auth_data[:hmac]
request['X-API-TIME'] = auth_data[:timestamp].to_s
request['X-API-ID'] = PUBLIC_KEY
response = http.request(request)
puts response.bodyC#
using System;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
class Program
{
const string PUBLIC_KEY = "XXXXXXX";
const string SECRET_KEY = "XXXXXXX";
const string API_URL = "https://api.regiondo.com/v1/...";
static string GetQueryString(string url)
{
var uri = new Uri(url);
return uri.Query;
}
static (long timestamp, string hmac) GetAuthHeader(string url)
{
var queryString = GetQueryString(url);
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
var requestData = $"{timestamp}{PUBLIC_KEY}{queryString}";
using (var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(SECRET_KEY)))
{
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(requestData));
var hmacDigest = BitConverter.ToString(hash).Replace("-", "").ToLower();
return (timestamp, hmacDigest);
}
}
static async Task Main(string[] args)
{
var (timestamp, hmac) = GetAuthHeader(API_URL);
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("X-API-HASH", hmac);
client.DefaultRequestHeaders.Add("X-API-TIME", timestamp.ToString());
client.DefaultRequestHeaders.Add("X-API-ID", PUBLIC_KEY);
var response = await client.GetAsync(API_URL);
var responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
}
}
}Java
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
public class Main {
private static final String PUBLIC_KEY = "XXXXXXX";
private static final String SECRET_KEY = "XXXXXXX";
private static final String API_URL = "https://api.regiondo.com/v1/...";
private static String getQueryString(String url) throws Exception {
URL uri = new URL(url);
return uri.getQuery();
}
private static String getAuthHeader(String url) throws Exception {
String queryString = getQueryString(url);
long timestamp = System.currentTimeMillis();
String requestData = timestamp + PUBLIC_KEY + (queryString != null ? queryString : "");
Mac sha256Hmac = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(SECRET_KEY.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
sha256Hmac.init(secretKey);
byte[] hashBytes = sha256Hmac.doFinal(requestData.getBytes(StandardCharsets.UTF_8));
StringBuilder hash = new StringBuilder();
for (byte b : hashBytes) {
hash.append(String.format("%02x", b));
}
return String.format("%d|%s", timestamp, hash.toString());
}
public static void main(String[] args) throws Exception {
String[] authData = getAuthHeader(API_URL).split("\\|");
long timestamp = Long.parseLong(authData[0]);
String hmac = authData[1];
URL url = new URL(API_URL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("X-API-HASH", hmac);
conn.setRequestProperty("X-API-TIME", Long.toString(timestamp));
conn.setRequestProperty("X-API-ID", PUBLIC_KEY);
int responseCode = conn.getResponseCode();
System.out.println("Response Code: " + responseCode);
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
}
}Go
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
"net/http"
"net/url"
"time"
)
const (
PublicKey = "XXXXXXX"
SecretKey = "XXXXXXX"
ApiURL = "https://api.regiondo.com/v1/..."
)
func getQueryString(rawUrl string) string {
parsedUrl, _ := url.Parse(rawUrl)
return parsedUrl.RawQuery
}
func getAuthHeader(requestUrl string) (string, string) {
queryString := getQueryString(requestUrl)
timestamp := time.Now().UnixNano() / int64(time.Millisecond)
requestData := fmt.Sprintf("%d%s%s", timestamp, PublicKey, queryString)
h := hmac.New(sha256.New, []byte(SecretKey))
h.Write([]byte(requestData))
hmacDigest := hex.EncodeToString(h.Sum(nil))
return fmt.Sprintf("%d", timestamp), hmacDigest
}
func main() {
timestamp, hmacDigest := getAuthHeader(ApiURL)
client := &http.Client{}
req, _ := http.NewRequest("GET", ApiURL, nil)
req.Header.Add("X-API-HASH", hmacDigest)
req.Header.Add("X-API-TIME", timestamp)
req.Header.Add("X-API-ID", PublicKey)
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error:", err)
return
}
defer resp.Body.Close()
fmt.Println("Response Status:", resp.Status)
}Swift
import Foundation
import CommonCrypto
let publicKey = "XXXXXXX"
let secretKey = "XXXXXXX"
let apiUrl = "https://api.regiondo.com/v1/..."
func getQueryString(from url: String) - String {
if let components = URLComponents(string: url) {
return components.query ?? ""
}
return ""
}
func getAuthHeader(for url: String) - (timestamp: String, hmac: String) {
let queryString = getQueryString(from: url)
let timestamp = String(Int(Date().timeIntervalSince1970 * 1000))
let requestData = timestamp + publicKey + queryString
let key = secretKey.data(using: .utf8)!
let data = requestData.data(using: .utf8)!
var hmacData = Data(count: Int(CC_SHA256_DIGEST_LENGTH))
_ = hmacData.withUnsafeMutableBytes { hmacBytes in
data.withUnsafeBytes { dataBytes in
key.withUnsafeBytes { keyBytes in
CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256), keyBytes, key.count, dataBytes, data.count, hmacBytes)
}
}
}
let hmac = hmacData.map { String(format: "%02hhx", $0) }.joined()
return (timestamp, hmac)
}
let authHeader = getAuthHeader(for: apiUrl)
var request = URLRequest(url: URL(string: apiUrl)!)
request.addValue(authHeader.hmac, forHTTPHeaderField: "X-API-HASH")
request.addValue(authHeader.timestamp, forHTTPHeaderField: "X-API-TIME")
request.addValue(publicKey, forHTTPHeaderField: "X-API-ID")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print("Error:", error)
return
}
if let data = data {
print("Response Data:", String(data: data, encoding: .utf8)!)
}
}
task.resume()
Dart/Flutter
import 'dart:convert';
import 'dart:io';
import 'package:crypto/crypto.dart';
const String publicKey = 'XXXXXXX';
const String secretKey = 'XXXXXXX';
const String apiUrl = 'https://api.regiondo.com/v1/...';
String getQueryString(String url) {
Uri uri = Uri.parse(url);
return uri.query;
}
Map getAuthHeader(String url) {
String queryString = getQueryString(url);
int timestamp = DateTime.now().millisecondsSinceEpoch;
String requestData = '$timestamp$publicKey$queryString';
var key = utf8.encode(secretKey);
var bytes = utf8.encode(requestData);
var hmacSha256 = Hmac(sha256, key);
var digest = hmacSha256.convert(bytes);
return {
'timestamp': timestamp.toString(),
'hmac': digest.toString()
};
}
void main() async {
var authHeader = getAuthHeader(apiUrl);
HttpClient client = HttpClient();
HttpClientRequest request = await client.getUrl(Uri.parse(apiUrl));
request.headers.set('X-API-HASH', authHeader['hmac']);
request.headers.set('X-API-TIME', authHeader['timestamp']);
request.headers.set('X-API-ID', publicKey);
HttpClientResponse response = await request.close();
String reply = await response.transform(utf8.decoder).join();
print('Response: $reply');
}BASH
PUBLIC_KEY="XXXXXXX"
SECRET_KEY="XXXXXXX"
API_URL="https://api.regiondo.com/v1/..."
# Function to extract the query string from the URL
get_query_string() {
local url="$1"
local query_string="${url#*\?}"
if [[ "$query_string" == "$url" ]]; then
echo ""
else
echo "$query_string"
fi
}
get_auth_header() {
local url="$1"
local query_string
query_string=$(get_query_string "$url")
local timestamp
timestamp=$(($(date +%s%N)/1000000)) # Current time in milliseconds
local request_data="${timestamp}${PUBLIC_KEY}${query_string}"
local hmac_digest
hmac_digest=$(echo -n "$request_data" | openssl dgst -sha256 -hmac "$SECRET_KEY" | sed 's/^.* //')
echo "$timestamp" "$hmac_digest"
}
read -r timestamp hmac <><(get_auth_header>
curl -X GET "$API_URL" \
-H "X-API-HASH: $hmac" \
-H "X-API-TIME: $timestamp" \
-H "X-API-ID: $PUBLIC_KEY"