Webhooks σε custom εφαρμογές: retries, idempotency και ασφαλής εκτέλεση
Τα webhooks είναι από τα πιο χρήσιμα και ταυτόχρονα πιο υποτιμημένα κομμάτια μιας custom εφαρμογής. Συνδέουν την εφαρμογή σας με πληρωμές, CRM, ERP, e-shop, φόρμες, email εργαλεία και AI αυτοματισμούς.
Το πρόβλημα είναι ότι ένα webhook δεν είναι απλώς «ένα request που έρχεται από τρίτο σύστημα». Είναι ένα γεγονός που μπορεί να έρθει καθυστερημένα, να αποτύχει, να επαναληφθεί ή να φτάσει με διαφορετική σειρά από αυτή που περιμένετε.
Αν δεν σχεδιαστεί σωστά, μπορεί να δημιουργήσει διπλές παραγγελίες, λάθος status πληρωμής, πολλαπλά emails στον ίδιο πελάτη ή αυτοματισμούς που τρέχουν ξανά και ξανά.
Τι είναι πρακτικά ένα webhook
Ένα webhook είναι ένας τρόπος να ενημερώνει ένα σύστημα ένα άλλο σύστημα όταν συμβαίνει κάτι.
Για παράδειγμα:
- έγινε πληρωμή σε Stripe ή Viva
- δημιουργήθηκε παραγγελία στο e-shop
- συμπληρώθηκε φόρμα ενδιαφέροντος
- άλλαξε status σε CRM
- ολοκληρώθηκε ένα AI workflow
- ανέβηκε αρχείο σε portal
Αντί η εφαρμογή σας να ρωτάει συνεχώς «έγινε κάτι;», το άλλο σύστημα στέλνει ένα event όταν υπάρχει αλλαγή.
Ακούγεται απλό. Η πραγματική δυσκολία αρχίζει όταν η παραγωγή δεν φέρεται σαν demo.
Γιατί τα webhooks αποτυγχάνουν στην πράξη
Τα webhooks μπορούν να αποτύχουν για πολλούς συνηθισμένους λόγους:
- ο server σας καθυστέρησε να απαντήσει
- υπήρξε προσωρινό πρόβλημα δικτύου
- το τρίτο σύστημα έκανε retry
- το ίδιο event έφτασε δύο φορές
- δύο events έφτασαν σχεδόν ταυτόχρονα
- το endpoint άλλαξε χωρίς σωστό deployment
- μια εξωτερική υπηρεσία είχε downtime
Πολλά σοβαρά APIs, όπως το Stripe, αντιμετωπίζουν τα webhooks ως μηχανισμό που πρέπει να αντέχει retries και καθυστερήσεις. Η λογική είναι σωστή: αν ένα σημαντικό event δεν παραδοθεί, το σύστημα πρέπει να ξαναπροσπαθήσει.
Για την εφαρμογή σας όμως αυτό σημαίνει ότι πρέπει να μπορεί να δέχεται το ίδιο μήνυμα παραπάνω από μία φορά χωρίς να χαλάει η κατάσταση των δεδομένων.
Idempotency: η λέξη που σώζει δεδομένα
Idempotency σημαίνει ότι η ίδια ενέργεια μπορεί να εκτελεστεί πολλές φορές αλλά το τελικό αποτέλεσμα παραμένει το ίδιο.
Παράδειγμα λάθους:
- webhook πληρωμής έρχεται δύο φορές
- η εφαρμογή δημιουργεί δύο τιμολόγια
- ο πελάτης παίρνει δύο emails
- το CRM δείχνει δύο ίδιες κινήσεις
Παράδειγμα σωστής συμπεριφοράς:
- webhook πληρωμής έρχεται δύο φορές
- η εφαρμογή αναγνωρίζει ότι το event έχει ήδη επεξεργαστεί
- επιστρέφει επιτυχές response
- δεν επαναλαμβάνει την επιχειρησιακή ενέργεια
Αυτό συνήθως γίνεται με αποθήκευση ενός μοναδικού event id ή idempotency key στη βάση. Πριν τρέξει ο handler, η εφαρμογή ελέγχει αν το event έχει ήδη καταγραφεί ως processed ή processing.
Μην κάνετε όλη τη δουλειά μέσα στο webhook request
Ένα συχνό λάθος είναι να προσπαθεί η εφαρμογή να κάνει τα πάντα πριν απαντήσει στο webhook.
Για παράδειγμα, μέσα στο ίδιο request:
- ελέγχει την υπογραφή
- ενημερώνει παραγγελία
- καλεί CRM
- στέλνει email
- δημιουργεί PDF
- ενημερώνει dashboard
- τρέχει AI ταξινόμηση
Αυτό αυξάνει τον κίνδυνο timeout. Αν το τρίτο σύστημα δεν πάρει γρήγορα επιτυχές response, μπορεί να κάνει retry, ακόμη κι αν η εφαρμογή σας είχε ήδη ξεκινήσει μέρος της δουλειάς.
Καλύτερη αρχιτεκτονική:
- παραλαμβάνετε το webhook
- ελέγχετε υπογραφή και βασική εγκυρότητα
- αποθηκεύετε το event
- επιστρέφετε γρήγορα 200 όταν είναι ασφαλές
- εκτελείτε τη βαριά δουλειά σε queue ή background worker
Έτσι η εφαρμογή γίνεται πιο προβλέψιμη και πιο εύκολη στο debugging.
Υπογραφές και αυθεντικότητα
Ένα webhook endpoint είναι δημόσια προσβάσιμο URL. Αυτό σημαίνει ότι δεν πρέπει να εμπιστεύεται οποιοδήποτε request μοιάζει σωστό.
Πρέπει να ελέγχετε:
- signature header από τον πάροχο
- timestamp όπου υποστηρίζεται
- σωστό content type
- επιτρεπτό event type
- αναμενόμενο account ή tenant id
- replay protection όπου χρειάζεται
Το webhook δεν πρέπει να βασίζεται μόνο στο ότι «κανείς δεν ξέρει το URL». Τα URLs διαρρέουν, αντιγράφονται σε logs, μπαίνουν σε screenshots και αλλάζουν χέρια.
Observability: χωρίς logs, δεν υπάρχει έλεγχος
Όταν ένα webhook χαλάσει, η πρώτη ερώτηση είναι πάντα ίδια: τι ακριβώς έφτασε και τι έκανε η εφαρμογή;
Ένα σωστό σύστημα κρατάει:
- event id
- provider
- event type
- received timestamp
- processing status
- αριθμό retries
- τελευταίο error
- συνδεδεμένη επιχειρησιακή οντότητα, όπως order ή lead
Δεν χρειάζεται να αποθηκεύονται ευαίσθητα δεδομένα χωρίς λόγο. Χρειάζεται όμως αρκετό ίχνος ώστε να μπορεί η ομάδα να καταλάβει τι συνέβη.
Πού βοηθάει η Ai Foundry
Στην Ai Foundry αντιμετωπίζουμε τα webhooks ως κομμάτι της αρχιτεκτονικής της εφαρμογής, όχι ως πρόχειρο endpoint στο τέλος του project. Αυτό έχει μεγάλη σημασία σε e-shop, CRM, portals, συστήματα κρατήσεων και AI automations, όπου ένα event μπορεί να επηρεάσει πραγματικές παραγγελίες, πελάτες ή εσωτερικές εργασίες.
Σχεδιάζουμε τη ροή με idempotency, καθαρά statuses, retries, queues, logs και ελέγχους ασφαλείας από την αρχή. Έτσι η εφαρμογή δεν δουλεύει μόνο όταν όλα πάνε καλά, αλλά παραμένει ελέγξιμη και όταν κάτι καθυστερήσει, αποτύχει ή ξανασταλεί.
Checklist πριν βγει live ένα webhook
Πριν εμπιστευτείτε production δεδομένα σε webhooks, ελέγξτε τα εξής:
- υπάρχει verification της υπογραφής
- υπάρχει μοναδικό event id στη βάση
- η ίδια ενέργεια δεν εκτελείται δύο φορές
- το endpoint απαντάει γρήγορα
- οι βαριές εργασίες μπαίνουν σε queue
- υπάρχουν logs και statuses
- υπάρχουν alerts για συνεχόμενες αποτυχίες
- υπάρχει τρόπος replay ή manual reconciliation
- τα errors δεν αποκαλύπτουν τεχνικά μυστικά
- το σύστημα έχει δοκιμαστεί με duplicate events
Συμπέρασμα
Τα webhooks είναι μικρά στην επιφάνεια αλλά κρίσιμα στο βάθος. Αν τα δείτε σαν απλό callback, αργά ή γρήγορα θα δημιουργήσουν διπλές ενέργειες και δύσκολα bugs. Αν τα σχεδιάσετε ως αξιόπιστη event ροή, γίνονται η βάση για σοβαρούς αυτοματισμούς.
Για custom εφαρμογές, e-shop, CRM και agentic AI workflows, το σωστό webhook design είναι διαφορά ανάμεσα στο «δουλεύει στο test» και στο «αντέχει στην καθημερινή χρήση».
Πηγές για περαιτέρω ανάγνωση: Stripe idempotent requests, Stripe process undelivered webhook events, Stripe event destinations and retries.