☰ Μενού · Webhooks
Webhooks
Λάβετε ένα HTTPS POST όταν συμβαίνει κάτι: καταχωρίζεται απόδειξη από οπουδήποτε, ξεκλειδώνει μια επιβράβευση, στέλνεται παραγγελία από τραπέζι.
Τα συμβάντα καλύπτουν ό,τι γίνεται μέσω του API σε αυτή την επιχείρηση, από τη δική σας σύνδεση και από οποιαδήποτε άλλη (άλλο ταμείο, kiosk, σύνδεση κρατήσεων). Εγγραφείτε μόνο στα συμβάντα που χρησιμοποιείτε.
Προσθέστε endpoint
Στο Προγραμματιστές → Webhooks ή μέσω του API. Το URL πρέπει να είναι δημόσιο HTTPS. Το μυστικό υπογραφής επιστρέφεται μία φορά, κατά τη δημιουργία του endpoint.
curl https://loyaltyfy.io/api/v1/webhook_endpoints \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://pos.example.com/loyaltyfy/webhooks",
"events": ["transaction.completed", "order.created"]
}'{
"object": "webhook_endpoint",
"id": "01c2a784-4bcf-43b9-8ac9-ddbad7a25341",
"url": "https://pos.example.com/loyaltyfy/webhooks",
"description": null,
"events": ["transaction.completed", "order.created"],
"status": "enabled",
"disabled_reason": null,
"livemode": false,
"created_at": "2026-10-06T18:17:32.381+00:00",
"secret": "whsec_UvjHvXfPk80ITYl_xPeAtskI0WjR8-PS"
}Τι λαμβάνετε
POST /loyaltyfy/webhooks HTTP/1.1
Content-Type: application/json
User-Agent: Loyaltyfy-Webhooks/1.0
Loyaltyfy-Signature: t=1791310488,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd{
"id": "evt_5a1f0c9e2b7d4e3f81a0c6d2",
"object": "event",
"type": "order.created",
"created": 1791310488,
"livemode": true,
"data": {
"object": {
"object": "order",
"id": "0c69a81c-0fbc-4333-b26c-789566b9bea4",
"number": 10,
"status": "new",
"table": "7",
...
}
}
}Το data.object είναι το ίδιο αντικείμενο που επιστρέφει το API (συναλλαγή, μέλος, παραγγελία), όπως ήταν τη στιγμή του συμβάντος. Απαντήστε με οποιοδήποτε 2xx μέσα σε 10 δευτερόλεπτα. Κάντε τη χρονοβόρα επεξεργασία αφού απαντήσετε.
Επαληθεύστε την υπογραφή
Η κεφαλίδα Loyaltyfy-Signature περιέχει χρονοσφραγίδα t και υπογραφή v1: το HMAC-SHA256 του t, μιας τελείας και του ακατέργαστου σώματος του αιτήματος, με κλειδί το μυστικό του endpoint σας, σε hex. Υπολογίστε το πάνω στα ακριβή bytes που λάβατε, πριν από οποιοδήποτε parsing του JSON, συγκρίνετε σε σταθερό χρόνο και απορρίψτε χρονοσφραγίδες παλαιότερες των πέντε λεπτών.
import crypto from "node:crypto";
// rawBody: the request body exactly as received (a string or Buffer, not parsed JSON)
export function verifyLoyaltyfy(rawBody, header, secret, toleranceSec = 300) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
const t = Number(parts.t);
if (!t || Math.abs(Date.now() / 1000 - t) > toleranceSec) return false;
const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
const a = Buffer.from(expected);
const b = Buffer.from(parts.v1 ?? "");
return a.length === b.length && crypto.timingSafeEqual(a, b);
}import hmac, hashlib, time
def verify_loyaltyfy(raw_body: bytes, header: str, secret: str, tolerance: int = 300) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
t = int(parts.get("t", "0"))
if abs(time.time() - t) > tolerance:
return False
signed = f"{t}.".encode() + raw_body
expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, parts.get("v1", ""))Επαναλήψεις
Αν το endpoint σας δεν απαντήσει 2xx εγκαίρως, επαναλαμβάνουμε μετά από 1 λεπτό, 5 λεπτά, 30 λεπτά, 2 ώρες, 6 ώρες, 12 ώρες και 24 ώρες. Μετά από 20 συνεχόμενες αποτυχημένες αποστολές το endpoint απενεργοποιείται και η επιχείρηση βλέπει τον λόγο στον πίνακα ελέγχου· ενεργοποιήστε το ξανά με PATCH /v1/webhook_endpoints/{id} και enabled: true.
Λόγω των επαναλήψεων ένα συμβάν μπορεί να φτάσει περισσότερες από μία φορές, και τα συμβάντα μπορεί να φτάσουν εκτός σειράς. Χρησιμοποιήστε το id του συμβάντος για να παραλείπετε τα διπλότυπα και τις χρονοσφραγίδες του ίδιου του αντικειμένου για να κρίνετε ποιο είναι νεότερο.
Δοκιμάστε ένα endpoint
curl -X POST https://loyaltyfy.io/api/v1/webhook_endpoints/01c2a784-4bcf-43b9-8ac9-ddbad7a25341/test \
-H "Authorization: Bearer sk_test_..."
# { "object": "webhook_test", "delivered": true, "status_code": 200, "error": null }Η πλήρης λίστα συμβάντων βρίσκεται στην αναφορά Συμβάντων.