REST API לניהול הרשמות Webhook

ככל שהעסק שלך גדל, הגדרות webhook סטטיות כבר לא מספקות: הוספת נמענים חדשים, ניהול הרשאות ומעקב אחר מסירות הופכים למשימה מורכבת. אנחנו בונים REST API לניהול מנויים שמבצע אוטומציה של כל התהליך—החל מרישום נקודות קצה ועד לסיבוב סודות והשבתה אוטומטית של מנויים לא פעילים. הצוות שלנו מספק את הפרויקט במפתח מלא, ומבטיח פעילות אמינה ותמיכה שוטפת.

פיתוח ותחזוקה של כל סוגי האתרים:

אתרי מידע או יישומי אינטרנט
אתרי תדמית, דפי נחיתה, אתרי חברה, קטלוגים מקוונים, חידונים, אתרי קידום, בלוגים, מקורות חדשות, פורטלי מידע, פורומים, אגרגטורים
אתרי מסחר אלקטרוני או יישומי אינטרנט
חנויות מקוונות, פורטלי B2B, שווקים, בורסות מקוונות, אתרי קאשבק, בורסות, פלטפורמות דרופשיפינג, מנתחי מוצרים
יישומי אינטרנט לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, פורטלים ארגוניים, מערכות ניהול ייצור, מנתחי מידע
אתרי שירות אלקטרוני או יישומי אינטרנט
פלטפורמות מודעות, בתי ספר מקוונים, בתי קולנוע מקוונים, בוני אתרים, פורטלים לשירותים אלקטרוניים, פלטפורמות אירוח וידאו, פורטלים נושאיים

אלה רק חלק מהסוגים הטכניים של אתרים שאנו עובדים איתם, ולכל אחד מהם יכולים להיות מאפיינים ופונקציונליות ספציפיים משלו, וכן ניתן להתאים אותם לצרכים ולמטרות הספציפיים של הלקוח.

השירותים שאנו מציעים
מציג 1 מתוך 1כל 2062 השירותים
REST API לניהול הרשמות Webhook
בינוני
~2-3 ימים

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1359
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1330
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1077
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1113
  • פיתוח אתר עבור SBH Partners
    פיתוח אתר עבור SBH Partners
    1201
  • פיתוח אתר עבור Red Pear
    פיתוח אתר עבור Red Pear
    619

תארו לעצמכם: חנות מקוונת מעבדת 1,000 הזמנות ביום, וכל הזמנה צריכה להיות מועברת ל-CRM, למערכת מחסן, לשירות אנליטיקה ולשתי APIs של שותפים. נקודות קצה (endpoints) של webhook המקודדות באופן סטטי בקובץ תצורה עובדות עבור MVP, אבל ככל שתגדלו, תיתקלו במספר הולך וגדל של נמענים ובצורך לאפשר ללקוחות לנהל את המנויים בעצמם. אנו בונים REST API לניהול מנויי webhook הפותר בעיות אלו. הניסיון שלנו: 5+ שנים ולמעלה מ-50 פרויקטים עם אינטגרציות webhook, המבטיחים זמינות של 99.9% ואספקה יציבה של עד 10,000 אירועים בשנייה. תמיכה לאחר ההשקה כלולה. הלקוחות שלנו חוסכים בדרך כלל 3,000–5,000 דולר בשנה על תחזוקה בהשוואה לתצורות סטטיות.

נניח שכבר יש לכם מערכת אירועים (למשל, על Laravel) ואתם רוצים להוסיף יכולת מנוי לשירותים חיצוניים. הגישה שלנו כוללת את השלבים הבאים: 1. תכנון סכמת מסד נתונים למנויים עם אינדוקס לחיפושים מהירים. 2. יישום נקודות קצה של REST עבור CRUD מלא, סיבוב סודות (secret rotation) ובדיקות. 3. בניית מפזר אירועים (event dispatcher) המתאים מנויים ומכניס משלוחים לתור. 4. הגדרת לוגיקת ניסיונות חוזרים, מעקב אחר כשלים והשבתה אוטומטית. 5. הפקת תיעוד OpenAPI. הכל מוכן לשימוש תוך 1-1.5 שבועות החל מ-2,500 דולר. בקשו ייעוץ כדי לדון בתרחיש שלכם.

מדוע תצורת webhook סטטית אינה מתאימה לסביבת ייצור?

נקודות קצה מקודדות (בקובצי תצורה) נשברות כאשר:

  • יש יותר משניים או שלושה נמענים.
  • לקוחות צריכים להוסיף/להסיר נקודות קצה ללא פריסה (deploy).
  • נדרש סינון לפי סוג אירוע עבור כל מנוי.
  • יש צורך לעקוב אחר הצלחת משלוח ושגיאות עבור כל נקודת קצה.

מערכת מנויים פותרת בעיות אלו באמצעות API אחיד, ומפחיתה את העומס התפעולי ב-60%.

כיצד אנו מיישמים את API המנויים?

אנו משתמשים ב-Laravel ו-PostgreSQL. כל מנוי מאוחסן בטבלה:

CREATE TABLE webhook_subscriptions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    consumer_id UUID NOT NULL REFERENCES consumers(id),
    endpoint_url TEXT NOT NULL,
    secret TEXT NOT NULL, -- hmac-секрет для верификации
    description TEXT,
    events TEXT[] NOT NULL, -- ['order.created', 'order.updated', '*']
    is_active BOOLEAN DEFAULT true,
    headers JSONB DEFAULT '{}', -- дополнительные заголовки для запроса
    timeout_seconds INTEGER DEFAULT 10,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW(),
    last_delivery_at TIMESTAMPTZ,
    failure_count INTEGER DEFAULT 0, -- счётчик последовательных неудач
    disabled_at TIMESTAMPTZ -- NULL = активна
);
CREATE TABLE webhook_event_types (
    name TEXT PRIMARY KEY, -- 'order.created'
    description TEXT,
    example_payload JSONB,
    is_active BOOLEAN DEFAULT true
);

התבנית CREATE TABLE webhook_subscriptions ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), consumer_id UUID NOT NULL REFERENCES consumers(id), endpoint_url TEXT NOT NULL, secret TEXT NOT NULL, -- hmac-секрет для верификации description TEXT, events TEXT[] NOT NULL, -- ['order.created', 'order.updated', '*'] is_active BOOLEAN DEFAULT true, headers JSONB DEFAULT '{}', -- дополнительные заголовки для запроса timeout_seconds INTEGER DEFAULT 10, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW(), last_delivery_at TIMESTAMPTZ, failure_count INTEGER DEFAULT 0, -- счётчик последовательных неудач disabled_at TIMESTAMPTZ -- NULL = активна ); CREATE TABLE webhook_event_types ( name TEXT PRIMARY KEY, -- 'order.created' description TEXT, example_payload JSONB, is_active BOOLEAN DEFAULT true ); באירועים פירושה הרשמה לכל האירועים—נוחה לניפוי באגים וללוחות מחוונים. נקודות הקצה העיקריות של ה-API:

מתודה נקודת קצה תיאור
POST /webhooks/subscriptions יצירת מנוי
GET /webhooks/subscriptions רשימת מנויים עבור צרכן
GET /webhooks/subscriptions/{id} פרטי מנוי
PATCH /webhooks/subscriptions/{id} עדכון מנוי
DELETE /webhooks/subscriptions/{id} מחיקת מנוי
POST /webhooks/subscriptions/{id}/test שליחת אירוע בדיקה
GET /webhooks/event-types רשימת סוגי אירועים זמינים

יצירת מנוי

בעת היצירה, אנו מאמתים סוגי אירועים, בודקים את נגישות נקודת הקצה ושולחים מיד אירוע בדיקה. הסוד מוצג רק בעת היצירה.

class WebhookSubscriptionController extends Controller
{
    public function store(StoreSubscriptionRequest $request): JsonResponse
    {
        $validated = $request->validated(); // ['endpoint_url', 'events', 'description?', 'headers?']

        $invalidEvents = array_diff(
            array_filter($validated['events'], fn($e) => $e !== '*'),
            WebhookEventType::where('is_active', true)->pluck('name')->toArray()
        );

        if (!empty($invalidEvents)) {
            return response()->json([
                'error' => 'Unknown event types',
                'invalid_events' => $invalidEvents,
            ], 422);
        }

        $reachable = $this->probeEndpoint($validated['endpoint_url']);

        $subscription = WebhookSubscription::create([
            'consumer_id' => $request->consumer()->id,
            'endpoint_url' => $validated['endpoint_url'],
            'secret' => Str::random(32),
            'events' => $validated['events'],
            'description' => $validated['description'] ?? null,
            'headers' => $validated['headers'] ?? [],
        ]);

        SendTestWebhookJob::dispatch($subscription);

        return response()->json([
            'id' => $subscription->id,
            'endpoint_url' => $subscription->endpoint_url,
            'events' => $subscription->events,
            'secret' => $subscription->secret,
            'created_at' => $subscription->created_at,
            'test_sent' => true,
        ], 201);
    }
}

סיבוב סודות ואימות

כדי לשנות את הסוד מבלי לאבד אירועים, אנו משתמשים בתקופת מעבר. נוצר סוד חדש, והישן נשאר תקף למשך 10 דקות.

public function rotateSecret(WebhookSubscription $subscription): JsonResponse
{
    $this->authorize('update', $subscription);
    $newSecret = Str::random(32);
    $subscription->update([
        'secret_old' => $subscription->secret,
        'secret' => $newSecret,
        'secret_rotated_at' => now(),
    ]);
    return response()->json([
        'secret' => $newSecret,
        'valid_until' => now()->addMinutes(10)->toIso8601String(),
        'note' => 'Old secret valid for 10 minutes during rotation',
    ]);
}

האימות בודק את שני המפתחות: תחילה את החדש, ולאחר מכן את הישן אם הוא עדיין בתקופת המעבר.

השבתה אוטומטית במקרה של כשלים

אם נקודת קצה אינה נגישה, לאחר 100 כשלים רצופים המנוי מושבת אוטומטית והבעלים מקבל הודעה.

class WebhookFailureTracker {
    public function recordFailure(WebhookSubscription $subscription): void {
        $subscription->increment('failure_count');
        if ($subscription->failure_count >= 100 && $subscription->is_active) {
            $subscription->update([
                'is_active' => false,
                'disabled_at' => now(),
            ]);
            Notification::send(
                $subscription->consumer,
                new WebhookSubscriptionDisabled($subscription)
            );
        }
    }

    public function recordSuccess(WebhookSubscription $subscription): void {
        $subscription->update([
            'failure_count' => 0,
            'last_delivery_at' => now(),
        ]);
    }
}

שיגור אירועים

כאשר מתרחש אירוע (למשל, *), אנו מוצאים את כל המנויים הפעילים התואמים לו ויוצרים משימה למשלוח.

class WebhookDispatcher {
    public function dispatch(string $eventType, array $payload): void {
        $subscriptions = WebhookSubscription::where('is_active', true)
            ->where(function ($q) use ($eventType) {
                $q->whereJsonContains('events', $eventType)
                    ->orWhereJsonContains('events', '*');
            })
            ->get();

        foreach ($subscriptions as $subscription) {
            $delivery = WebhookDelivery::create([
                'subscription_id' => $subscription->id,
                'event_type' => $eventType,
                'payload' => $payload,
            ]);

            SendWebhookJob::dispatch($delivery);
        }
    }
}

app(WebhookDispatcher::class)->dispatch('order.created', [
    'id' => $order->id,
    'status' => $order->status,
    'total' => $order->total,
    'created_at' => $order->created_at,
]);

אילו מדדים אנו עוקבים?

כדי לנטר את איכות המשלוח, אנו עוקבים אחר אינדיקטורים מרכזיים:

מדד ערך יעד תיאור
שיעור משלוח מוצלח > 99.9% חלק האירועים שנמסרו בניסיון הראשון
זמן השהיה ממוצע < 500 אלפיות השנייה זמן מפרסום האירוע ועד לקבלתו
מספר מנויים פעילים עד 10,000 לכל צרכן
תדירות סיבוב סודות כל 90 יום שינוי מפתח מתוכנן
אירועים מעובדים בשנייה עד 10,000 על שרת יחיד, ניתן להרחבה אופקית

אבטחת חתימת HMAC

חתימת HMAC היא קריטית לאבטחה מכיוון שהיא מבטיחה שהאירוע נשלח על ידי המערכת שלכם. אנו משתמשים ב-SHA-256 ודורשים אימות חתימה בצד הלקוח.

כיצד תצורה סטטית משתווה למערכת מנויים?

מאפיין נקודות קצה מקודדות API מנויים
ניהול באמצעות קוד/פריסה באמצעות REST API
סינון אירועים זהה לכולם לפי מנוי
מדרגיות עד 2-3 נמענים עד 10,000 מנויים
סובלנות לתקלות ללא השבתה אוטומטית השבתה אוטומטית לאחר 100 שגיאות
ניטור רישום ידני לוח מחוונים מובנה עם התראות
עלות תחזוקה שנתית ~8,000 דולר (מוערך) ~2,000 דולר (אוטומטי)

מה כלול בעבודה

  • REST API עם לוגיקת CRUD מלאה לניהול מנויים.
  • אימות סוגי אירועים ובדיקת נגישות נקודת קצה.
  • סיבוב סודות עם תקופת מעבר (10 דקות).
  • השבתה אוטומטית במקרה של כשלים והודעת בעלים בדוא"ל.
  • אירוע בדיקה בעת יצירת מנוי.
  • תיעוד בפורמט OpenAPI (Swagger).
  • רישום משלוחים וניטור (לוח מחוונים של Grafana).
  • שבועיים של תמיכה לאחר המסירה.

Webhook הוא מנגנון שבו שרת שולח בקשת HTTP לכתובת URL נתונה כאשר מתרחש אירוע. ויקיפדיה — ויקיפדיה

מדוע המערכת שלנו טובה יותר מפתרונות מוכנים?

בניגוד לתוספים של CMS, הקוד שלנו ממוקד בביצועים: הוא מטפל בעד 10,000 אירועים בשנייה על שרת יחיד ומתרחב אופקית באמצעות תורים. אנו משתמשים בחתימות HMAC לאבטחה. אנו מבטיחים יציבות המבוססת על 5+ שנות ניסיון בפרויקטים בעלי עומס גבוה. החיסכון בזמן האינטגרציה מגיע עד 40% הודות ל-SDKs מוכנים ללקוח. קבלו הצעה מסחרית החל מ-2,500 דולר—נדון בפרטי הפרויקט שלכם.

צרו קשר כדי להזמין פיתוח של מערכת webhook לפרויקט שלכם.