Guide d’intégration QR
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 :
Exemple fonctionnel (avec les clés secrètes 123456 + ABCDEF) :
Pour générer un QR valide, vous avez besoin de trois éléments :
- Votre code émetteur (4 caractères, fourni par Roommatik)
- Votre clé secrète émetteur et la clé secrète de l’hôtel (fournies par Roommatik)
- 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
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
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 |
YYYYMMDDTHHMMEx : 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
- 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 - Construire la clé secrète : concaténer la clé de l’émetteur + la clé de l’hôtel. Exemple :
123456+ABCDEF=123456ABCDEF - Calculer HMAC-SHA1 du payload avec la clé concaténée comme secret
- Encoder le résultat HMAC (20 octets) en Base64 — c’est la valeur de
SIGNATURE
Exemples de code
Python
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
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.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
Génération du code 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 :
- freeformatter.com/hmac-generator — générateur HMAC en ligne (sélectionnez SHA1)
- base64.guru/converter/encode/hex — convertir hex en Base64
