Los Lagos Hotel logo

Los Lagos Hotel

Dernière mise à jour

Introduction

Los Lagos Hotel est un hôtel familial d'El Calafate, la ville de Patagonie que la plupart des voyageurs prennent comme base pour visiter le glacier Perito Moreno. Au démarrage de ce travail, l'hôtel migrait de Minihotel, un système de gestion plus ancien, vers Cloudbeds. C'est cette migration qui a rendu le reste possible : dès lors que les chambres, les tarifs et les réservations vivaient dans un système doté d'une vraie API, l'hôtel pouvait enfin vendre en direct depuis son propre site et maîtriser ses propres prix.

J'ai donc construit deux applications web. La première est le site bilingue sur lequel les clients réservent ; la seconde est l'outil interne avec lequel l'hôtel fixe ses prix. Elles ne se ressemblent pas du tout, et c'est voulu. L'une est une vitrine, l'autre un arrière-guichet. Ce qu'elles partagent, c'est le backend, et toutes deux dialoguent avec le même compte Cloudbeds.

La commande

Le problème financier n'était pas compliqué. Une part importante des réservations arrivait via Booking.com et des plateformes similaires, et chacune s'accompagne d'une commission. L'hôtel avait déjà un site, et ces clients auraient donc pu réserver en direct. Mais le site n'inspirait pas assez confiance pour qu'on y saisisse sa carte, et il n'était pas simple à utiliser. Les deux coûtaient des conversions, et les commissions continuaient d'être versées.

Vendre en direct paraît simple jusqu'à ce qu'on regarde ce que l'hôtel doit gérer en Argentine. Cloudbeds encaisse en pesos argentins, mais l'hôtel et les spécialistes du revenue qui fixent ses prix travaillent en dollars, car le peso bouge assez souvent pour qu'un prix fixé en pesos devienne faux en une semaine. Et les clients résidant hors d'Argentine sont exonérés des 21 % de TVA sur l'hébergement, si bien que la même chambre a légitimement deux prix selon le lieu de résidence du client.

Ces deux points retombaient sur la réception, traités au cas par cas. La commande se résumait donc à trois choses : prendre les réservations sur le site de l'hôtel lui-même, rendre ce site digne de confiance au moment de saisir une carte, et afficher à chaque client le prix qui le concerne réellement sans que personne ne fasse les calculs à la main.

Technologies

Le site client est en Next.js avec TypeScript, prégénéré statiquement dans chaque langue. L'outil interne est une SPA React construite avec Vite. Supabase est le backend commun : Postgres, la sécurité au niveau des lignes et les Edge Functions. Les deux applications finissent par écrire dans l'API Cloudbeds.

Next.js icon
React icon
TypeScript icon
Supabase icon

Site un : le site destiné aux clients

Le site public est bilingue. L'espagnol conserve les URLs sans préfixe, en préservant les chemins qu'utilise déjà le site actuel de l'hôtel, et l'anglais se trouve sous /en. Le visiteur qui arrive pour la première fois n'a pas à le chercher : le site lit la langue demandée par son navigateur, l'oriente en conséquence et retient ce choix dans un cookie pendant un an, avec un sélecteur dans l'en-tête pour qui préfère l'autre. Chaque page est prégénérée dans les deux langues afin que les robots reçoivent du vrai HTML plutôt qu'une coquille vide. Au-delà des chambres et de l'hôtel lui-même, l'essentiel du contenu répond aux questions que les gens se posent réellement avant de s'engager dans un voyage en Patagonie : à quelle distance se trouve le centre, comment arriver depuis l'aéroport, que faire une fois sur place.

Deux détails que j'ai particulièrement aimé construire. Les sections sont séparées par des transitions SVG courbes plutôt que par le trait droit habituel. Et la page de localisation intègre une carte OpenStreetMap interactive avec des repères personnalisés pour l'hôtel ainsi que pour les restaurants, sites touristiques et banques alentour, accompagnés des temps de trajet à pied et en voiture jusqu'au centre, à la gare routière, à l'aéroport et au glacier. Les notes de TripAdvisor, Google et Booking sont regroupées sur une seule bande pour éviter au client d'aller les chercher.

Los Lagos Hotel homepage hero with the availability search

La page d'accueil : la bannière, les raisons de réserver en direct et la recherche de disponibilité

Adapter le moteur de réservation à l'hôtel

La page de réservation intègre l'Immersive Experience de Cloudbeds, un composant web tiers qui affiche son propre tunnel de commande dans le site. C'est en pratique une boîte noire : tout ce dont l'hôtel avait besoin par-dessus est ajouté par un unique observateur qui surveille le DOM du composant et réapplique les ajustements à chaque nouveau rendu. Ce que cette couche apporte :

  • Un sélecteur de résidence. Le client indique s'il vit en Argentine ou à l'étranger, ce qui détermine si les 21 % de TVA s'appliquent à ce qu'il voit, et inscrit un indicateur de facturation sur la réservation pour que l'exonération soit appliquée en aval, sans que la réception ait à saisir la nationalité à la main.
  • Des prix qui remontent au dollar. Le prix durable de l'hôtel est en dollars tandis que le client est facturé en pesos, et la conversion s'appuie sur un taux que le site récupère via une route d'API dotée d'une plage de vraisemblance, d'une limite de fraîcheur, d'un dernier taux valide en secours et d'un mode dégradé qui préfère ne pas convertir plutôt que d'utiliser un taux approximatif.
  • Un sélecteur de literie que Cloudbeds ne propose pas. Le client choisit un lit double ou deux lits simples pour chaque chambre, avec des compteurs bornés par ce qui est réellement libre cette nuit-là. Les identifiants des chambres physiques utilisés pour ce calcul restent sur le serveur et n'atteignent jamais le navigateur.
  • Un détail de prix enregistré. Le net, la TVA et le total dans les deux devises, ainsi que le taux de change utilisé, sont inscrits sur chaque réservation sous forme de champs personnalisés, afin que la réception facture à partir de chiffres capturés au moment de la réservation plutôt que recalculés des jours plus tard.
  • L'attribution automatique des chambres. À la fin d'une réservation, un webhook lit la configuration de lits demandée et attribue les chambres physiques compatibles. Il laisse délibérément l'attribution de Cloudbeds inchangée lorsqu'aucune chambre compatible n'est libre, plutôt que de placer quelqu'un dans le mauvais lit.

Le bug le plus instructif est venu de cet observateur. Piloter le compteur de quantité propre à Cloudbeds provoquait un nouveau rendu du composant, qui redéclenchait l'observateur, qui pilotait à nouveau le compteur. Un seul clic générait plus de 600 000 mutations du DOM et figeait l'onglet. La correction a été une protection contre la réentrance autour de la passe d'ajustement, et tout code qui touche au DOM de Cloudbeds doit désormais s'exécuter à l'intérieur.

Cloudbeds booking engine with the residency toggle and bed-type selector

Le moteur de réservation, avec le sélecteur de résidence et celui de literie

Site deux : l'outil de gestion des tarifs

Certains systèmes de gestion hôtelière intègrent des outils de revenue qui feraient une partie de ce travail. Le problème est la dépendance : la logique de tarification finit par vivre dans le produit d'un tiers, et en sortir plus tard coûte cher. Pour ce client, la flexibilité comptait davantage : la logique de tarification vit donc dans une application distincte, la sienne, qui parle à Cloudbeds via son API au lieu de résider à l'intérieur.

La seconde application est celle où l'hôtel fixe ses prix. Elle est strictement interne. Il n'y a pas d'inscription publique, et les comptes sont créés par un administrateur. Les deux rôles, tarification et personnel de l'hôtel, sont appliqués par la sécurité au niveau des lignes dans Postgres puis revérifiés à l'intérieur de chaque fonction privilégiée, plutôt que simplement masqués dans la navigation.

  • Un calendrier des prix qui fonctionne en dollars. L'hôtel fait appel à des sociétés de revenue management externes, et le dollar est la devise dans laquelle elles fixent les prix : c'est donc en dollars qu'elles saisissent, un prix de base pour une journée ou pour une plage de dates entière, ou un import groupé par CSV lorsqu'une saison complète est retarifée d'un coup. Chaque type de chambre en dérive son propre prix via un pourcentage, l'arrondit au palier supérieur de vingt centimes et le convertit en pesos au taux de Cloudbeds. Tarifer dans la devise dans laquelle elles raisonnent réellement est ce qui rend une tarification intelligente possible ici.
  • Une publication qui vérifie son propre travail. La publication se fait en deux temps, aperçu puis validation. L'aperçu montre exactement quelles lignes seront envoyées et ce que Cloudbeds recevra, et après validation l'application relit les tarifs depuis Cloudbeds et marque chacun comme confirmé, envoyé ou en échec selon la réponse.
  • Une surveillance du taux de change. Une fonction planifiée lit le cours officiel de la Banco Nación, ne l'enregistre que s'il a réellement changé, recalcule tous les prix en pesos à partir de leur source durable en dollars, et ouvre une tâche pour le personnel. Cette tâche ne se referme pas d'un simple clic. La valider relit les réglages de devise de Cloudbeds et n'aboutit que s'ils concordent.
  • Tout l'environnement opérationnel : un journal d'activité, la gestion de l'équipe, une section d'aide rédigée pour le personnel de l'hôtel et non pour des développeurs, et une sécurité de compte avec authentification à deux facteurs et clés d'accès.

Ne pas automatiser cette dernière étape est précisément l'intention. Une monnaie comme le peso argentin peut bouger brutalement et sans grand préavis : un système qui retariferait toutes les chambres dès qu'un flux bouge serait un risque plutôt qu'un confort, car une lecture erronée ou purement passagère se propagerait directement dans les prix en production, et l'hôtel s'en apercevrait en vendant ses chambres trop bon marché. Observer un cours ne déplace donc jamais un prix à lui seul. Le système enregistre le taux, recalcule ce que seraient les nouveaux prix, et ouvre une tâche. Les prix ne bougent qu'une fois qu'une personne a confirmé que le taux est réellement appliqué dans Cloudbeds. Cloudbeds dispose bien de sa propre conversion automatique, actualisée deux fois par jour depuis un flux international, mais pour cet hôtel ni la fréquence ne suffit ni la référence n'est la bonne : ce qu'il facture, c'est le cours officiel de la Banco Nación, pas un taux moyen international.

Le point faible d'une étape de confirmation humaine, c'est qu'il faut que quelqu'un la remarque. Les mêmes Edge Functions qui ouvrent une tâche FX l'envoient donc aussi à un groupe Telegram, via un bot que j'ai écrit pour l'hôtel : l'ancien taux, le nouveau, son origine (flux automatique ou saisie manuelle), et un bouton qui mène directement à la page des tâches de l'outil d'exploitation. Il publie de nouveau lorsque quelqu'un applique le taux, en indiquant qui l'a fait, et si le cours revient à sa valeur précédente avant que quiconque n'ait agi, il publie une annulation pour éviter un travail inutile. La notification est délibérément au mieux et ne peut jamais lever d'erreur. La tâche FX est déjà enregistrée au moment où le message est tenté : un jeton manquant ou une panne de Telegram ne doivent pas pouvoir casser l'enregistrement des taux.

Rate Ops dashboard with the latest USD/ARS rate and pending tasks

Tableau de bord : dernier taux de change, tâches en attente et taux d'occupation

Confidentialité, consentement et analytique

L'Argentine dispose de son propre régime de protection des données, la Ley 25.326, supervisé par l'AAIP, et les sites ont été construits en conformité avec lui plutôt qu'adaptés après coup. Le site client comporte une politique de confidentialité et une politique de cookies rédigées selon cette loi, avec les droits Habeas Data qu'elle accorde et la manière de les exercer, et le tunnel de réservation ne collecte que ce dont une réservation a réellement besoin.

Le consentement est appliqué dans le code, pas seulement décrit sur une page. Il existe exactement une catégorie non essentielle sur le site client, l'analytique, et rien de ce qui s'y rapporte ne se charge tant que le visiteur n'a pas donné son accord explicite. Trois éléments ne sont jamais bloqués : la préférence de langue, le moteur de réservation lui-même et l'enregistrement du choix. C'est ce qui satisfait la règle du consentement préalable de la Ley 25.326, ainsi que le RGPD et l'ePrivacy pour les clients européens, nombreux dans cet hôtel.

Derrière cette barrière se trouvent PostHog pour l'analytique produit et le rejeu de session, aux côtés de Google Analytics, afin que l'hôtel voie comment les gens circulent réellement sur le site et à quel moment ils abandonnent une réservation, au lieu de le supposer. L'outil interne a sa propre documentation : une notice de confidentialité pour le personnel, un registre des activités de traitement, et une politique de conservation réellement mise en oeuvre, avec une tâche planifiée qui purge le journal d'activité au bout de 24 mois et les journaux de requêtes Cloudbeds au bout de 90 jours.

Pourquoi deux applications et non une seule

Les deux moitiés ont des exigences réellement différentes. Le site client est public et doit être indexable : il est donc prégénéré pour chaque langue. L'outil d'exploitation n'a aucune surface SEO et n'a jamais besoin de rendu serveur : c'est donc une simple application monopage qui dialogue directement avec Supabase. Plus légère, moins coûteuse et plus simple à raisonner.

Le backend est la moitié commune. Tout ce qui est sensible s'exécute dans Postgres ou dans une Edge Function : le jeton Cloudbeds, la clé de service, l'écriture des taux de change. Aucun des deux navigateurs ne détient jamais d'identifiant Cloudbeds.

Le résultat

L'outil d'exploitation est en production et l'hôtel s'en sert pour fixer ses prix : modifier les tarifs revient désormais à saisir un nombre une fois, à le prévisualiser, à le publier et à le vérifier auprès de Cloudbeds, au lieu d'une passe manuelle sur chaque type de chambre et chaque date. En août 2026, le site client est terminé et attend la bascule depuis le site actuel de l'hôtel ; les réservations directes y arriveront alors, chaque client voyant le prix qui le concerne.

Une bonne partie du travail n'était pas du code. Comme c'est la réception qui encaisse réellement les clients, le projet a aussi produit des guides en espagnol pour l'encaissement par lien de paiement : comment vérifier la résidence déclarée par le client, confirmer que le taux de change est toujours à jour, et rapprocher le montant de Cloudbeds avant de facturer quoi que ce soit.

Deux applications pour un petit hôtel : une vitrine qui doit survivre à Google, et un arrière-guichet qui doit survivre à un taux de change mouvant.

Merci de votre lecture,

Julio Macias Gonzalez

Me contacter