Guide d’intégration QR

Version du document 3.0 — Dernière mise à jour : mars 2026.
Les kiosques et distributeurs de clés Roommatik interprètent les codes QR au format décrit ci-dessous pour délivrer une clé codée selon les informations contenues. Les codes QR peuvent être générés entièrement hors ligne.

Démarrage rapide

Un code QR Roommatik valide a cette structure :

<ÉMETTEUR|DATE_ÉMISSION|DATE_ACTIVATION|DATE_EXPIRATION|CHAMBRE|TYPE|PORTES|ID_QR|MAX_CARTES|SIGNATURE>

Exemple fonctionnel (avec les clés secrètes 123456 + ABCDEF) :

<ACME|20210412T1800|20210413T1200|20210415T1330|101|N|000A|ab3245re12|2|IeuEuUyoxK8rsaONgn24hQ5UJbg=>

Pour générer un QR valide, vous avez besoin de trois éléments :

  1. Votre code émetteur (4 caractères, fourni par Roommatik)
  2. Votre clé secrète émetteur et la clé secrète de l’hôtel (fournies par Roommatik)
  3. Les données de la réservation (chambre, dates, etc.)

Options d’intégration

Option Cas d’utilisation Connexion PMS
Option 1 — Données complètes dans le QR La chambre est déjà attribuée (ex. : émettre des clés pour des clients hébergés) Non requise
Option 2 — Numéro de réservation dans le QR La chambre n’est pas encore attribuée au moment de la génération du QR Requise (chambre et checkout consultés lors de la lecture)

Option 1 — Données complètes dans le QR

Toutes les informations nécessaires pour encoder la clé sont incluses dans le code QR, y compris le numéro de chambre. L’appareil Roommatik n’a besoin que de se connecter au serveur du logiciel de serrures.

Format

<ABCD|ISSUE_DATE_TIME|ACTIVATION_DATE_TIME|EXPIRY_DATE_TIME|ROOM_IDENTIFIER|CARD_TYPE|COMMON_DOORS_MASK|QR_UNIQUE_ID|MAX_CARDS_PER_QR|SIGNATURE>

Option 2 — Numéro de réservation dans le QR

Le code QR contient uniquement le numéro de réservation. Les distributeurs et kiosques Roommatik consulteront la chambre et la date de checkout auprès du PMS lors de la lecture.

Format

<ABCD|ISSUE_DATE_TIME|RESERVATION_NUMBER|COMMON_DOORS_MASK|QR_UNIQUE_ID|MAX_CARDS_PER_QR|SIGNATURE>

Référence des champs

Champ Description Format / Valeurs
ABCD Identifiant unique de l’émetteur du code QR. Fourni par Roommatik Max 4 caractères alphanumériques
ISSUE_DATE_TIME Date/heure à partir de laquelle l’appareil peut émettre la clé. Le QR n’est valide qu’entre cet instant et EXPIRY_DATE_TIME YYYYMMDDTHHMM
Ex : 20260315T1400
ACTIVATION_DATE_TIME Date/heure de début encodée sur la carte. Si omis (champ vide), la date/heure d’émission est utilisée YYYYMMDDTHHMM (optionnel)
EXPIRY_DATE_TIME Date/heure d’expiration encodée sur la carte (typiquement l’heure de checkout) YYYYMMDDTHHMM
ROOM_IDENTIFIER Identifiant unique de la chambre. Doit correspondre exactement à l’ID utilisé dans le logiciel de serrures (sensible à la casse) Max 8 caractères
CARD_TYPE Type de carte clé à émettre N = Nouvelle (invalide les cartes précédentes)
C = Copie (les cartes précédentes restent valides)
COMMON_DOORS_MASK Masque hexadécimal pour les autorisations de portes communes. Voir explication détaillée ci-dessous 4 caractères hex (2 octets = 16 portes)
Ex : 000A
QR_UNIQUE_ID Identifiant unique du code QR. Utilisé pour la traçabilité et les journaux de l’hôtel Max 10 caractères
MAX_CARDS_PER_QR Nombre maximum de clés à émettre pour ce QR. La limite effective est le minimum entre cette valeur et le maximum configuré sur l’appareil Entier (optionnel, champ vide = illimité)
RESERVATION_NUMBER Identifiant de la réservation (Option 2 uniquement). Le PMS renvoie la chambre et la date de checkout Chaîne de caractères
SIGNATURE Signature HMAC-SHA1 du payload, encodée en Base64. Voir calcul de la signature 28 caractères Base64

Portes communes (COMMON_DOORS_MASK)

Le masque est une valeur hexadécimale de 4 caractères (2 octets) où chaque bit représente une porte. Le bit de poids le plus faible (LSB) correspond à la porte 0.

Exemple hex Binaire Portes actives
0000 0000 0000 0000 0000 Aucune
0001 0000 0000 0000 0001 Porte 0
000A 0000 0000 0000 1010 Portes 1 et 3
0007 0000 0000 0000 0111 Portes 0, 1 et 2
FFFF 1111 1111 1111 1111 Toutes (0–15)

Pour calculer le masque : additionnez 2^n pour chaque porte n à activer, puis convertissez le résultat en hexadécimal complété à 4 caractères.

Calcul de la signature

La signature garantit que le code QR a été généré par un émetteur autorisé. Si la signature est incorrecte, le distributeur rejettera le code.
  1. Extraire le payload : tout ce qui se trouve entre < et le dernier | (aucun des deux inclus). Dans l’exemple : ACME|20210412T1800|20210413T1200|20210415T1330|101|N|000A|ab3245re12|2
  2. Construire la clé secrète : concaténer la clé de l’émetteur + la clé de l’hôtel. Exemple : 123456 + ABCDEF = 123456ABCDEF
  3. Calculer HMAC-SHA1 du payload avec la clé concaténée comme secret
  4. Encoder le résultat HMAC (20 octets) en Base64 — c’est la valeur de SIGNATURE

Exemples de code

Python

import hmac, hashlib, base64

def generate_roommatik_qr(
issuer: str,
issuer_secret: str,
hotel_secret: str,
issue_dt: str, # “YYYYMMDDTHHMM”
activation_dt: str, # “YYYYMMDDTHHMM” ou “”
expiry_dt: str, # “YYYYMMDDTHHMM”
room: str,
card_type: str, # “N” ou “C”
doors_mask: str, # “0000”
qr_id: str,
max_cards: str = “”, # “” = illimité
) -> str:
fields = [issuer, issue_dt, activation_dt, expiry_dt,
room, card_type, doors_mask, qr_id, max_cards] payload = “|”.join(fields)
key = (issuer_secret + hotel_secret).encode()
sig = hmac.new(key, payload.encode(), hashlib.sha1).digest()
signature = base64.b64encode(sig).decode()
return f”<{payload}|{signature}>”

# Exemple
qr = generate_roommatik_qr(
issuer=”ACME”,
issuer_secret=”123456″,
hotel_secret=”ABCDEF”,
issue_dt=”20210412T1800″,
activation_dt=”20210413T1200″,
expiry_dt=”20210415T1330″,
room=”101″,
card_type=”N”,
doors_mask=”000A”,
qr_id=”ab3245re12″,
max_cards=”2″,
)
print(qr)
# <ACME|20210412T1800|…|IeuEuUyoxK8rsaONgn24hQ5UJbg=>

JavaScript / Node.js

import { createHmac } from “crypto”;

function generateRoommatikQR({
issuer, // “ACME”
issuerSecret, // “123456”
hotelSecret, // “ABCDEF”
issueDt, // “YYYYMMDDTHHMM”
activationDt, // “YYYYMMDDTHHMM” ou “”
expiryDt, // “YYYYMMDDTHHMM”
room, // “101”
cardType, // “N” | “C”
doorsMask, // “0000”
qrId, // “ab3245re12”
maxCards = “”, // “” = illimité
}) {
const fields = [issuer, issueDt, activationDt, expiryDt,
room, cardType, doorsMask, qrId, maxCards];
const payload = fields.join(“|”);
const key = issuerSecret + hotelSecret;
const sig = createHmac(“sha1”, key).update(payload).digest(“base64”);
return `<${payload}|${sig}>`;
}

// Exemple
const qr = generateRoommatikQR({
issuer: “ACME”,
issuerSecret: “123456”,
hotelSecret: “ABCDEF”,
issueDt: “20210412T1800”,
activationDt: “20210413T1200”,
expiryDt: “20210415T1330”,
room: “101”,
cardType: “N”,
doorsMask: “000A”,
qrId: “ab3245re12”,
maxCards: “2”,
});
console.log(qr);

C#

using System.Security.Cryptography;
using System.Text;

string GenerateRoommatikQR(
string issuer, string issuerSecret, string hotelSecret,
string issueDt, string activationDt, string expiryDt,
string room, string cardType, string doorsMask,
string qrId, string maxCards = “”)
{
var fields = new[] { issuer, issueDt, activationDt, expiryDt,
room, cardType, doorsMask, qrId, maxCards };
var payload = string.Join(“|”, fields);
var key = Encoding.UTF8.GetBytes(issuerSecret + hotelSecret);
using var hmac = new HMACSHA1(key);
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(payload));
var signature = Convert.ToBase64String(hash);
return $”<{payload}|{signature}>”;
}

Exemple complet pas à pas

Données d’entrée

Donnée Valeur
Code émetteur ACME
Clé secrète émetteur 123456
Clé secrète hôtel ABCDEF
Émission du QR 12 avr 2021 à 18h00
Check-in 13 avr 2021 à 12h00
Check-out 15 avr 2021 à 13h30
Chambre 101
Type de carte N (nouvelle, invalide les précédentes)
Portes communes Portes 1 et 3 → 000A
ID du QR ab3245re12
Max cartes 2

Calcul de la signature

Étape Valeur
1. Payload ACME|20210412T1800|20210413T1200|20210415T1330|101|N|000A|ab3245re12|2
2. Clé combinée 123456ABCDEF
3. HMAC-SHA1 (hex) 21eb84b94ca8c4af2bb1a38d827db8850e5425b8
4. Base64 IeuEuUyoxK8rsaONgn24hQ5UJbg=

QR résultant

<ACME|20210412T1800|20210413T1200|20210415T1330|101|N|000A|ab3245re12|2|IeuEuUyoxK8rsaONgn24hQ5UJbg=>

Génération du code QR

Recommandations pour générer l’image QR :

  • Niveau de correction d’erreurs : M (15 %) ou supérieur
  • Encodage : alphanumérique ou byte (UTF-8)
  • Taille minimale : 3 cm × 3 cm imprimés
  • Contraste : noir sur fond blanc, ne pas inverser
  • Zone de silence : conserver au moins 4 modules de marge blanche autour du QR

Erreurs courantes

Symptôme Cause probable Solution
Le distributeur rejette le QR Signature incorrecte Vérifiez que le payload n’inclut pas les caractères <, > ni le dernier |. Vérifiez que les clés sont concaténées dans le bon ordre (émetteur + hôtel)
QR « expiré » ISSUE_DATE_TIME est dans le futur ou EXPIRY_DATE_TIME est dépassé Ajustez les dates. Aucun fuseau horaire n’est appliqué : les valeurs sont interprétées comme l’heure locale de l’appareil
La clé n’ouvre pas la porte ROOM_IDENTIFIER ne correspond pas au logiciel de serrures Demandez à Roommatik la liste des IDs de chambre configurés
Le QR est lu mais ne distribue pas MAX_CARDS_PER_QR atteint Générez un nouveau QR avec un QR_UNIQUE_ID différent
Erreur de lecture du QR QR trop petit ou faible contraste Imprimez au minimum 3 cm × 3 cm, noir sur blanc, avec marge

Outils utiles

Pour vérifier manuellement le calcul de la signature :

Besoin d’aide ? Contactez l’équipe d’intégrations Roommatik via le chat de support technique sur le portail.