অধ্যায় ৭.৪ — ওয়েবহুক
১. উদ্দেশ্য
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}withenabled: 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