Nuestra API está diseñada para tener URLs orientadas a recursos y predecibles, y para usar códigos de respuesta HTTP que indiquen errores de la API. Utilizamos funciones HTTP integradas, como los verbos HTTP, que pueden ser comprendidos por clientes HTTP estándar. Actualmente, todas las respuestas de la API devolverán únicamente formato JSON, incluyendo errores y datos.
Workflow de la API
El diagrama a continuación ilustra las dos fases principales: la Gestión del Catálogo (navegación por categorías y ofertas) y el Proceso de Checkout (disponibilidad, reserva y confirmación).
1. Configura tu entorno de prueba
1.1. Autenticación
- La autenticación utiliza principios simples basados en HMAC.
- Para consultas de prueba, utiliza tu clave PÚBLICA. Puedes encontrar tu clave en tu Panel de mando de Regiondo, en Conectividad > Configuración del API > Generar claves
1.2. Entorno de pruebas (Sandbox) vs. entorno de producción
- Las ofertas creadas en tu cuenta Live de Regiondo no aparecerán en el Sandbox Environment y no podrán recuperarse a través de la clave pública.
- Para probar tu implementación de la API, necesitarás una cuenta de Regiondo en el Sandbox Environment y publicar tus ofertas en regiondo-dev-de.de
Nunca envíes tu Clave segura con llamadas a la API. Envía solo la Clave pública abiertamente, y utiliza la Clave segura de tu parte para encriptar y firmar las solicitudes.
2. Documentación
Notas:
- Hay ejemplos de código disponibles en GitHub: https://github.com/regiondo-dev/api
- Al utilizar una URL de solicitud, elimina el prefijo
sandbox-y asegúrate de que no haya espacios adicionales al final de la URL.
3. Configuración de la autenticación
Para conectarte a la API de Regiondo, debes seguir unos pasos fundamentales para garantizar una transmisión de datos segura y precisa. Esta guía te llevará a través del proceso y señalará los problemas más comunes que podrían ocasionar un error 401 Unauthorized. Sigue estas instrucciones con atención para evitar problemas habituales.
3.1. Headers
Cada solicitud debe incluir los siguientes headers:
X-API-HASH: {{regiondoHmacAuthHeader}}
X-API-TIME: {{regiondoReqTime}}
X-API-ID: XXXXXXX3.2. Pre-request Script
Este script genera el timestamp y el HMAC requeridos a partir de tu Clave pública y tu Clave segura:
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. Problemas comunes que generan errores 401 Unauthorized
4.1. Integración incorrecta del header
Asegúrate de que los headers estén correctamente integrados en tus solicitudes. Comprueba que los nombres y valores de los headers coincidan con el ejemplo proporcionado. Cualquier discrepancia en los nombres o valores de los headers puede provocar un fallo en la autenticación.
4.2. Problemas con la integración de la Clave segura
Asegúrate de que la Clave segura (SECRET_KEY) esté correctamente implementada en tu script de pre-request. Cualquier error en la Clave segura provocará un fallo en el proceso de autenticación. Comprueba que el script esté copiando correctamente la Clave segura y generando el HMAC digest.
4.3. Formato de fecha incorrecto
El formato de fecha en tus solicitudes debe seguir la codificación correcta. En lugar de usar comas (,), debes codificarlas como %2C en la URL. Por ejemplo, las fechas deben tener el siguiente formato:
2024-06-01%2C2024-07-01
5. Ejemplos de scripts de conexión
Los siguientes ejemplos muestran cómo conectarte a la API de Regiondo en distintos lenguajes de programación. Reemplaza todos los valores de marcador de posición (p. ej., XXXXXXX) con tus credenciales reales y una URL de endpoint válida.
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"