Webhooks
Webhooks
Με τα Webhooks λαμβάνετε ειδοποιήσεις σε πραγματικό χρόνο όταν προκύπτουν συμβάντα στον χώρο εργασίας σας — π.χ. όταν σαρώνεται ένας κωδικός QR.
Δημιουργία Webhook
POST /v1/webhooks{ "url": "https://example.com/webhooks/qr3", "events": ["qr.scanned", "qr.created"], "secret": "my-secret-key-min-16-chars"}Απόκριση
{ "id": "wh_abc123", "url": "https://example.com/webhooks/qr3", "events": ["qr.scanned", "qr.created"], "is_active": true, "secret": "my-secret-key-min-16-chars", "secret_hint": "my-s…", "created_at": "2026-03-15T10:00:00.000Z"}Τύποι συμβάντων
| Συμβάν | Περιγραφή |
|---|---|
* | Όλα τα συμβάντα |
qr.created | Ο κωδικός QR δημιουργήθηκε |
qr.updated | Ο κωδικός QR ενημερώθηκε (URL, κατάσταση, ετικέτες) |
qr.deleted | Ο κωδικός QR διαγράφηκε |
qr.scanned | Ο κωδικός QR σαρώθηκε |
qr.flagged | Ο κωδικός QR επισημάνθηκε ως μη ασφαλής |
scan.created | Συμβάν σάρωσης (ψευδώνυμο για το qr.scanned) |
workspace.updated | Ο χώρος εργασίας ενημερώθηκε |
webhook.ping | Δοκιμαστικό ping (μέσω του τελικού σημείου /ping) |
Μορφή Payload
Όλα τα payload των Webhook έχουν αυτή τη μορφή:
{ "id": "evt_abc123xyz", "type": "qr.scanned", "created": "2026-03-15T10:00:00.000Z", "data": { "code_id": "qr_abc123", "short_code": "r7f3Kx", "scan_id": "scn_xyz", "country": "AT", "device_type": "mobile", "os": "iOS" }}Επαλήθευση υπογραφής
Το qr3.app υπογράφει κάθε αίτημα Webhook με HMAC-SHA256:
X-QR3-Signature: sha256=a1b2c3d4e5f6...Υλοποίηση επαλήθευσης
import crypto from "crypto";
function verifySignature( payload: string, signature: string, secret: string): boolean { const expected = crypto .createHmac("sha256", secret) .update(payload) .digest("hex"); const received = signature.replace("sha256=", ""); return crypto.timingSafeEqual( Buffer.from(expected, "hex"), Buffer.from(received, "hex") );}
// In Express:app.post("/webhooks/qr3", (req, res) => { const signature = req.headers["x-qr3-signature"] as string; const valid = verifySignature( JSON.stringify(req.body), signature, process.env.QR3_WEBHOOK_SECRET ); if (!valid) return res.status(401).json({ error: "Invalid signature" });
const event = req.body; console.log(event.type, event.data); res.json({ received: true });});import hmacimport hashlib
def verify_signature(payload: str, signature: str, secret: str) -> bool: expected = hmac.new( secret.encode(), payload.encode(), hashlib.sha256 ).hexdigest() received = signature.removeprefix("sha256=") return hmac.compare_digest(expected, received)Λογική επαναπροσπάθειας
Σε περίπτωση σφαλμάτων (HTTP >= 300 ή λήξη χρονικού ορίου), το qr3.app προσπαθεί ξανά να παραδώσει το αίτημα:
| Προσπάθεια | Καθυστέρηση |
|---|---|
| 1 | Αμέσως |
| 2 | 1 λεπτό |
| 3 | 5 λεπτά |
Μετά από 10 συνεχόμενα σφάλματα, το Webhook απενεργοποιείται αυτόματα.
Καταγραφές παράδοσης
GET /v1/webhooks/:id/deliveries{ "data": [ { "id": "whd_abc123", "event_type": "qr.scanned", "status": "success", "status_code": 200, "response_time_ms": 145, "attempt": 1, "created_at": "2026-03-15T10:00:00.000Z" } ]}Δοκιμαστικό Ping
Δοκιμάστε ένα Webhook αμέσως:
POST /v1/webhooks/:id/pingΑυτό στέλνει ένα συμβάν webhook.ping στη διεύθυνση URL του τελικού σας σημείου.