ADR-003: Webhook Architecture
Status: Accepted Date: December 17, 2025 Decision Makers: CODITECT Engineering Team
Context
Stripe webhooks notify us of payment events. We need to:
- Handle events reliably (no missed events)
- Process idempotently (handle retries)
- Respond quickly (<5s per Stripe requirement)
- Handle high event volumes
Decision
Implement async webhook processing with idempotency.
Architecture
Stripe → Webhook Endpoint → Signature Verify → Idempotency Check → Queue → Worker
│
▼
Quick Response (200 OK)
Key Events to Handle
| Event | Action |
|---|---|
customer.subscription.created | Provision access |
customer.subscription.updated | Update limits |
customer.subscription.deleted | Revoke access |
invoice.paid | Record payment |
invoice.payment_failed | Notify, retry |
checkout.session.completed | Complete signup |
Implementation
@app.post("/webhooks/stripe")
async def stripe_webhook(request: Request):
# 1. Verify signature (fail fast)
# 2. Check idempotency (skip duplicates)
# 3. Queue for processing
# 4. Return 200 immediately
await queue.enqueue(event)
return {"status": "queued"}
Consequences
Positive
- Reliable event processing
- Fast response times
- Handles retries safely
Negative
- Queue infrastructure required
- Eventual consistency
Document Control:
- Created: December 17, 2025