এই ভলিউমে · ভলিউম 07
ইন্টিগ্রেশন
GDS (Amadeus, Sabre) NDC পাবলিক API ওয়েবহুক

অধ্যায় ৭.৪ — ওয়েবহুক

১. উদ্দেশ্য

travoBooks পার্টনার সিস্টেমকে event notify করে HTTPS POST দিয়ে। Polling-এর বিকল্প — efficient, real-time।

২. ইভেন্ট ট্যাক্সোনমি

ফরম্যাট: <resource>.<action>

ইভেন্ট কখন ফায়ার হয়
booking.created নতুন বুকিং তৈরি
booking.held সরবরাহকারী হোল্ড success
booking.issued টিকেট ইস্যু
booking.cancelled বাতিল
booking.refunded রিফান্ড সম্পূর্ণ
ticket.voided টিকেট ভয়েড
payment.captured পেমেন্ট সফল
payment.refunded পেমেন্ট রিফান্ড
payment.failed পেমেন্ট ব্যর্থ
invoice.issued ইনভয়েস issued
invoice.paid পরিশোধিত
memo.received ADM/ACM প্রাপ্ত
period.closed মাস ক্লোজড

৩. পেলোড ফরম্যাট

{
  "evt_id": "evt_a1b2c3...",
  "evt_type": "booking.issued",
  "evt_timestamp": "2026-05-26T08:00:00Z",
  "partner_id": "ptr_123",
  "data": {
    "booking_id": "bkg_456",
    "ticket_numbers": ["1234567890123"],
    "total_amount": "65400.00",
    "currency": "BDT"
  }
}

৪. সিগনেচার

HMAC-SHA256 header:

TravoBooks-Signature: t=1716732000,v1=5257a869e7ecebeda32affa62cdca3...
TravoBooks-Webhook-Id: whk_abc
TravoBooks-Event-Id: evt_a1b2c3

ভেরিফিকেশন: ১. t (timestamp) এক্সট্রাক্ট ২. বর্তমান সময়ের সাথে compare; 5 মিনিটের বেশি delta → reject (replay protection) ৩. signed payload = timestamp + "." + body ৪. HMAC-SHA256 কম্পিউট করুন আপনার webhook secret দিয়ে ৫. v1 এর সাথে compare — match না হলে → reject

৫. ডেলিভারি গ্যারান্টি

At-least-once: ইভেন্ট কমপক্ষে একবার delivered হবে। একাধিকবারও সম্ভব → consumer-এ idempotent processing।

ব্যর্থতা retry: exponential backoff: - 1 মিনিট - 5 মিনিট - 30 মিনিট - 2 ঘণ্টা - 12 ঘণ্টা - 24 ঘণ্টা সর্বোচ্চ 8 চেষ্টা।

8 চেষ্টার পরে → webhook dead-lettered, অ্যালার্ট পাঠানো।

৬. কনজিউমার দায়িত্ব

def handle_webhook(request):
    # 1. Verify signature
    if not verify_signature(request.headers, request.body, SECRET):
        return 401

    payload = json.loads(request.body)

    # 2. Idempotency check
    if already_processed(payload['evt_id']):
        return 200  # ack so travoBooks ভুলে যায়

    # 3. Process (within 10 seconds!)
    process_event(payload)

    # 4. Mark processed
    mark_processed(payload['evt_id'])

    return 200

গুরুত্বপূর্ণ: - HTTP 2xx within 10 seconds — অন্যথায় retry - Idempotent processing (evt_id দিয়ে dedupe) - Heavy work async queue-এ (return 2xx fast, process later)

৭. ইভেন্ট সাবস্ক্রিপশন

API দিয়ে:

POST /v1/webhooks
{
  "url": "https://partner.example.com/webhooks/travobooks",
  "event_types": ["booking.issued", "payment.captured"],
  "description": "Production webhook"
}

Response: webhook ID + secret (শুধু একবার দেখা)।

৮. ম্যানেজমেন্ট

  • List: GET /v1/webhooks
  • Update: PUT /v1/webhooks/{id}
  • Disable temporarily: PATCH /v1/webhooks/{id} with enabled: false
  • Delete: DELETE /v1/webhooks/{id}
  • Recent deliveries: GET /v1/webhooks/{id}/deliveries

৯. টেস্টিং

  • Test event: POST /v1/webhooks/{id}/test
  • Webhook secret rotation: POST /v1/webhooks/{id}/rotate-secret

১০. সাধারণ ফাঁদ

  • ⚠️ Signature verify না করা — spoofed events accepted
  • ⚠️ 10 সেকেন্ডে রেসপন্স ব্যর্থ — duplicate deliveries
  • ⚠️ Idempotency ছাড়া — duplicate processing
  • ⚠️ Replay protection স্কিপ — old events replay-vulnerable