Connecter ZKTeco à Odoo : L'Approche API Cloud (Sans VPN, Sans Logiciel Local)
La plupart des intégrations ZKTeco-Odoo nécessitent un accès réseau local, un VPN ou une IP fixe. Découvrez comment connecter vos pointeuses biométriques ZKTeco à Odoo — y compris Odoo Online et Odoo.sh — via une API REST cloud.
Introduction
Si vous avez cherché comment connecter ZKTeco à Odoo, vous avez probablement constaté que la réponse est bien plus compliquée qu'elle ne devrait l'être. Des dizaines de fils de discussion sur le forum communautaire Odoo posent la même question, et les réponses mènent presque toujours aux mêmes impasses : des bibliothèques Python locales qui ne fonctionnent que sur le même réseau local que l'appareil, des tunnels VPN que votre équipe informatique redoute, ou des configurations avec IP fixe qui exposent votre réseau à internet.
Ce tutoriel propose une approche différente. Au lieu de vous battre avec les contraintes réseau, nous utilisons une API REST cloud pour relier votre pointeuse biométrique ZKTeco à Odoo — que vous utilisiez Odoo Online, Odoo.sh ou une instance auto-hébergée.
Le Problème : Pourquoi l'Intégration ZKTeco-Odoo Est Compliquée
Les pointeuses biométriques ZKTeco (lecteurs d'empreintes digitales, terminaux de reconnaissance faciale) sont omniprésentes. Elles sont abordables, fiables et largement déployées. Odoo est l'un des ERP open-source les plus populaires. Connecter les deux devrait être simple. Ce n'est pas le cas.
Voici pourquoi.
Les Outils Traditionnels Sont Limités au Réseau Local
Les outils les plus courants pour communiquer avec les appareils ZKTeco sont :
pyzk — Une bibliothèque Python qui communique avec les appareils ZKTeco via le réseau local. Elle nécessite un accès réseau direct à l'appareil. Elle est open-source mais présente des bugs connus avec les firmwares récents et un suivi limité.
node-zklib — Un équivalent Node.js. Même contrainte : la machine exécutant le code doit être sur le même réseau que l'appareil. Plusieurs forks existent, aucun n'est définitif.
Modules de l'Odoo App Store — Plusieurs modules prétendent intégrer ZKTeco avec Odoo. Presque tous utilisent pyzk ou node-zklib en interne, ce qui signifie qu'ils héritent de la même obligation de réseau local.
Cela Ne Fonctionne Pas avec Odoo Hébergé dans le Cloud
Si vous utilisez Odoo Online (la plateforme SaaS d'Odoo), vous ne pouvez pas installer de bibliothèques Python personnalisées. Point final. L'approche pyzk est impossible.
Si vous utilisez Odoo.sh (la plateforme PaaS d'Odoo), vous ne pouvez pas installer de packages Python système nécessitant un accès réseau au matériel local. L'approche pyzk échoue également.
Même si vous auto-hébergez Odoo sur un VPS ou un serveur cloud, votre instance Odoo est dans un centre de données et votre pointeuse ZKTeco est dans vos locaux. Ils ne sont pas sur le même réseau. Pour faire fonctionner pyzk, vous avez besoin d'une de ces solutions de contournement :
Un tunnel VPN entre votre réseau de bureau et votre serveur — ajoute de la complexité, de la latence et un coût récurrent.
Une redirection de port sur votre routeur de bureau pour exposer l'appareil à internet — un risque de sécurité significatif.
Une IP fixe sur votre connexion internet — indisponible chez tous les FAI, et cela nécessite toujours une redirection de port.
Aucune de ces solutions n'est acceptable en production, surtout si vous gérez des pointeuses sur plusieurs sites.
L'Approche Cloud : Configurer Une Fois, Accéder de Partout
Il existe une meilleure architecture. Au lieu qu'Odoo tente d'accéder à votre réseau local pour récupérer les données de l'appareil, l'appareil envoie les données au cloud PunchConnect, et Odoo les récupère via une API REST standard.
Vous configurez l'appareil une seule fois via le tableau de bord PunchConnect. Ensuite, les données de présence circulent automatiquement vers le cloud. Votre instance Odoo les récupère via une API REST standard — sans logiciel local, sans VPN, sans IP fixe. Juste des appels HTTPS depuis n'importe où.
Cela fonctionne avec tous les modes de déploiement Odoo : Online, .sh et auto-hébergé. Consultez notre documentation API pour la référence complète des endpoints.
Pointeuse ZKTeco ──(sync auto)──> PunchConnect Cloud ──(API REST)──> Odoo
│
└──(Webhook)──> Votre serveur (optionnel)Étape par Étape : Connecter ZKTeco à Odoo avec PunchConnect
Prérequis
Une pointeuse biométrique ZKTeco (la plupart des modèles récents sont compatibles — y compris les séries K, uFace, SpeedFace, ProFace et MB).
Une instance Odoo (toute version, tout mode d'hébergement).
Un compte PunchConnect. Démarrez un essai gratuit de 7 jours — sans carte bancaire.
Étape 1 : Enregistrer Votre Appareil sur PunchConnect
Après avoir créé votre compte PunchConnect, vous recevrez un jeton API (préfixé par pc_live_). Utilisez-le pour enregistrer votre appareil.
Python :
JavaScript (Node.js) :
```javascript
const API_TOKEN = "pc_live_your_token_here";
const BASE_URL = "https://api.punchconnect.com";
const response = await fetch(${BASE_URL}/v1/devices, {
method: "POST",
headers: {
Authorization: Bearer ${API_TOKEN},
"Content-Type": "application/json",
},
body: JSON.stringify({
serial_number: "BFGH234900045",
name: "Main Entrance - Floor 1",
location: "Headquarters",
}),
});
const device = await response.json();
console.log(Device ID: ${device.id});
console.log(Status: ${device.status});
```
import requests
API_TOKEN = "pc_live_your_token_here"
BASE_URL = "https://api.punchconnect.com"
# Register a new device
response = requests.post(
f"{BASE_URL}/v1/devices",
headers={
"Authorization": f"Bearer {API_TOKEN}",
"Content-Type": "application/json"
},
json={
"serial_number": "BFGH234900045",
"name": "Main Entrance - Floor 1",
"location": "Headquarters"
}
)
device = response.json()
print(f"Device ID: {device['id']}")
print(f"Status: {device['status']}")Étape 2 : Connecter l'Appareil
Une fois enregistré, suivez les instructions de configuration dans le tableau de bord PunchConnect pour connecter votre pointeuse ZKTeco. Le processus prend environ 5 minutes par appareil — vous saisissez quelques paramètres sur le panneau d'administration de l'appareil, et il commence à se synchroniser automatiquement.
En moins de 60 secondes après la configuration, l'appareil apparaît comme « en ligne » dans votre tableau de bord. Vous pouvez vérifier via l'API :
response = requests.get(
f"{BASE_URL}/v1/devices",
headers={"Authorization": f"Bearer {API_TOKEN}"}
)
for device in response.json()["data"]:
print(f"{device['name']}: {device['status']}")
# Output: "Main Entrance - Floor 1: online"Étape 3 : Configurer les Webhooks pour la Présence en Temps Réel
Pour une synchronisation en temps réel de la présence, configurez un webhook. PunchConnect enverra les événements de pointage à votre URL dès qu'ils se produisent — sans polling.
Chaque requête POST du webhook inclut un payload JSON avec l'identifiant de l'employé, l'horodatage, les informations de l'appareil et le sens du pointage (entrée/sortie).
Si vous ne pouvez pas recevoir de webhooks (par exemple, sur Odoo Online), passez à l'Étape 4 — vous pouvez interroger l'API selon un calendrier à la place.
response = requests.post(
f"{BASE_URL}/v1/webhooks",
headers={
"Authorization": f"Bearer {API_TOKEN}",
"Content-Type": "application/json"
},
json={
"url": "https://your-odoo-instance.com/api/punchconnect/webhook",
"events": ["attendance.created"],
"secret": "your_webhook_secret"
}
)
webhook = response.json()
print(f"Webhook ID: {webhook['id']}")
print(f"Status: {webhook['status']}")Étape 4 : Récupérer les Données de Présence dans Odoo
C'est ici que tout se met en place. Ce script Python récupère les enregistrements de présence depuis PunchConnect et crée les entrées de présence dans Odoo via l'API XML-RPC d'Odoo.
Cela fonctionne depuis n'importe quelle machine ayant accès à internet — une tâche cron sur votre serveur, une action planifiée Odoo, ou même une fonction serverless.
Vous pouvez exécuter ce script comme une action planifiée Odoo (ir.cron) qui s'exécute toutes les 10-15 minutes, une tâche cron sur n'importe quel serveur, ou un gestionnaire de webhook qui traite les enregistrements en temps réel depuis l'Étape 3.
import requests
import xmlrpc.client
from datetime import datetime, timedelta
# ---------- PunchConnect Config ----------
PC_TOKEN = "pc_live_your_token_here"
PC_BASE = "https://api.punchconnect.com"
# ---------- Odoo Config ----------
ODOO_URL = "https://your-company.odoo.com"
ODOO_DB = "your-database"
ODOO_USER = "admin@yourcompany.com"
ODOO_PASSWORD = "your_api_key"
# ---------- Connect to Odoo ----------
common = xmlrpc.client.ServerProxy(f"{ODOO_URL}/xmlrpc/2/common")
uid = common.authenticate(ODOO_DB, ODOO_USER, ODOO_PASSWORD, {})
models = xmlrpc.client.ServerProxy(f"{ODOO_URL}/xmlrpc/2/object")
# ---------- Fetch Recent Attendance from PunchConnect ----------
since = (datetime.utcnow() - timedelta(hours=1)).isoformat() + "Z"
response = requests.get(
f"{PC_BASE}/v1/attendance",
headers={"Authorization": f"Bearer {PC_TOKEN}"},
params={
"since": since,
"limit": 100
}
)
records = response.json()["data"]
print(f"Fetched {len(records)} attendance records")
# ---------- Sync to Odoo ----------
for record in records:
# Look up the Odoo employee by badge ID
employee_ids = models.execute_kw(
ODOO_DB, uid, ODOO_PASSWORD,
"hr.employee", "search",
[[["barcode", "=", record["employee_id"]]]]
)
if not employee_ids:
print(f"No Odoo employee found for badge {record['employee_id']}, skipping")
continue
employee_id = employee_ids[0]
punch_time = record["timestamp"]
if record["direction"] == "in":
# Create check-in record
models.execute_kw(
ODOO_DB, uid, ODOO_PASSWORD,
"hr.attendance", "create",
[{"employee_id": employee_id, "check_in": punch_time}]
)
print(f"Check-in recorded for employee {employee_id} at {punch_time}")
elif record["direction"] == "out":
# Find open attendance and set check-out
open_attendance = models.execute_kw(
ODOO_DB, uid, ODOO_PASSWORD,
"hr.attendance", "search",
[[
["employee_id", "=", employee_id],
["check_out", "=", False]
]],
{"limit": 1, "order": "check_in desc"}
)
if open_attendance:
models.execute_kw(
ODOO_DB, uid, ODOO_PASSWORD,
"hr.attendance", "write",
[open_attendance, {"check_out": punch_time}]
)
print(f"Check-out recorded for employee {employee_id} at {punch_time}")Bonus : Synchroniser les Employés vers l'Appareil
Vous pouvez également pousser les employés depuis Odoo vers votre pointeuse ZKTeco via PunchConnect, de sorte que les nouvelles recrues apparaissent automatiquement sur l'appareil :
# Fetch employees from Odoo
employees = models.execute_kw(
ODOO_DB, uid, ODOO_PASSWORD,
"hr.employee", "search_read",
[[["active", "=", True]]],
{"fields": ["id", "name", "barcode"]}
)
# Sync to PunchConnect (which syncs to the device)
response = requests.post(
f"{PC_BASE}/v1/employees/sync",
headers={
"Authorization": f"Bearer {PC_TOKEN}",
"Content-Type": "application/json"
},
json={
"employees": [
{
"id": str(emp["barcode"]),
"name": emp["name"]
}
for emp in employees
if emp["barcode"]
]
}
)
result = response.json()
print(f"Synced {result['synced']} employees, {result['errors']} errors")Odoo Online vs Auto-Hébergé : Quelle Approche pour Quel Cas ?
Si vous utilisez Odoo Online, vous ne pouvez pas installer de bibliothèques Python personnalisées. L'approche pyzk/node-zklib est impossible. Une API REST cloud comme PunchConnect est votre seule option viable pour l'intégration biométrique ZKTeco.
Si vous utilisez Odoo.sh, vous ne pouvez pas installer de packages système qui communiquent avec du matériel local. Même résultat — les outils traditionnels basés sur le réseau local ne fonctionneront pas.
Si vous auto-hébergez Odoo sur un VPS ou un serveur cloud, vous pourriez techniquement configurer un VPN + pyzk, mais cela prend des heures, nécessite une surveillance continue du VPN et du réseau, et casse lorsque votre FAI change votre IP. Avec PunchConnect, la configuration prend moins de 30 minutes et fonctionne sur tous vos sites depuis une seule API.
L'approche traditionnelle vous limite également au polling uniquement (exécution périodique d'un script pour récupérer les données de l'appareil). PunchConnect prend en charge les webhooks en temps réel, de sorte que les événements de présence atteignent Odoo en quelques secondes après un pointage.
Pour les déploiements multi-sites, la différence est encore plus marquée. Une configuration VPN nécessite une configuration distincte par site. PunchConnect gère tous les appareils depuis un seul tableau de bord et une seule API — que vous ayez 2 appareils ou 200.
Tarification
PunchConnect coûte 200 $ par appareil (licence unique) plus 50 $/an pour les renouvellements à partir de la deuxième année. Il n'y a pas de frais par utilisateur, ce qui compte à grande échelle — que vous ayez 10 employés ou 10 000 par appareil, le prix est le même.
Des réductions de volume sont disponibles : 10+ appareils à 180 $, 25+ à 160 $, 50+ à tarification personnalisée. Consultez le détail complet sur notre page de tarification.
PunchConnect gère actuellement des charges de production avec 24 000+ employés sur plusieurs sites — il est donc éprouvé à grande échelle.
Questions Fréquentes
Peut-on connecter une pointeuse ZKTeco à Odoo Online sans logiciel local ? Oui. PunchConnect est une API REST cloud — votre pointeuse ZKTeco synchronise les données vers le cloud PunchConnect, et votre instance Odoo Online les récupère via des appels HTTPS standard. Aucun logiciel local, aucun VPN, aucune IP fixe requis.
Quels modèles ZKTeco sont compatibles avec PunchConnect ? La plupart des modèles ZKTeco récents sont pris en charge, y compris les séries K, uFace, SpeedFace, ProFace et MB. Si votre appareil dispose d'une capacité de serveur web/cloud intégrée, il fonctionnera. Contactez-nous si vous n'êtes pas sûr pour un modèle spécifique.
Est-ce que PunchConnect est conforme au RGPD ? PunchConnect traite des données biométriques de présence (identifiants d'employés et horodatages de pointage). Les données transitent de manière sécurisée via HTTPS et sont stockées avec chiffrement. Pour les exigences spécifiques de votre organisation concernant le traitement des données biométriques au sens du RGPD, contactez notre équipe pour discuter de votre cas d'utilisation.
Combien de temps faut-il pour configurer l'intégration ? La configuration complète prend environ 30 minutes : création du compte PunchConnect, enregistrement de l'appareil via l'API, connexion de la pointeuse via le tableau de bord, et mise en place du script de synchronisation Odoo. Le tout sans intervention sur votre infrastructure réseau.
Comment PunchConnect se compare-t-il à pyzk pour Odoo auto-hébergé ? pyzk nécessite un accès réseau local à l'appareil, ce qui implique des VPN ou des redirections de port pour les serveurs Odoo distants. PunchConnect fonctionne via internet sans configuration réseau. Il prend également en charge les webhooks pour les données en temps réel, alors que pyzk fonctionne uniquement en polling. Le compromis est le coût — pyzk est gratuit (open-source), PunchConnect coûte 200 $/appareil.
Commencer
Connecter une pointeuse ZKTeco à Odoo n'a pas besoin d'impliquer des VPN, des IP fixes ou des scripts locaux fragiles. L'approche API cloud est plus simple, plus sécurisée et fonctionne avec tous les modes de déploiement Odoo.
Démarrez votre essai gratuit de 7 jours — sans carte bancaire. Enregistrez votre appareil et connectez-le via le tableau de bord en environ 15 minutes. Ensuite, exécutez le script de synchronisation ci-dessus ou configurez les webhooks pour la présence en temps réel.
Si vous avez des questions sur l'intégration ou besoin d'aide avec votre modèle ZKTeco spécifique, contactez-nous via notre page contact. Nous avons de l'expérience avec pratiquement toutes les variantes de firmware ZKTeco existantes.