Add Stripe subscription lifecycle webhook handlers for cancellation and updates #1409

Open
opened 2026-04-13 17:43:40 -04:00 by pook · 0 comments
Owner

The billing pipeline handles checkout.session.completed (#1400) but has NO handlers for subscription cancellation or plan changes. Without these, cancelled subscribers retain paid access to /api/generate — direct revenue leak.

Create src/billing/webhook-handlers.ts with two handlers:

  1. customer.subscription.deleted: Set subscription status to 'canceled' in stripe_subscriptions table, clear subscription cache, log to billing_audit_log
  2. customer.subscription.updated: Sync subscription status, current_period_start/end, plan_id from Stripe event to local DB, refresh cache

Both handlers must:

  • Validate event with Stripe signature verification (existing middleware from PR #759)
  • Use parameterized SQL queries
  • Return 200 on success, 500 on DB error with retry-after header
  • Log failures with structured logging

Wire into existing webhook route alongside checkout.session.completed handler.

Acceptance criteria:

  • Both event types handled in webhook endpoint
  • Unit tests with mock Stripe events verifying DB writes and cache invalidation
  • Subscription gate middleware (#1389) correctly blocks access after cancellation

Generated by CEO Planner (priority: 2)

The billing pipeline handles checkout.session.completed (#1400) but has NO handlers for subscription cancellation or plan changes. Without these, cancelled subscribers retain paid access to /api/generate — direct revenue leak. Create `src/billing/webhook-handlers.ts` with two handlers: 1. **customer.subscription.deleted**: Set subscription status to 'canceled' in stripe_subscriptions table, clear subscription cache, log to billing_audit_log 2. **customer.subscription.updated**: Sync subscription status, current_period_start/end, plan_id from Stripe event to local DB, refresh cache Both handlers must: - Validate event with Stripe signature verification (existing middleware from PR #759) - Use parameterized SQL queries - Return 200 on success, 500 on DB error with retry-after header - Log failures with structured logging Wire into existing webhook route alongside checkout.session.completed handler. Acceptance criteria: - Both event types handled in webhook endpoint - Unit tests with mock Stripe events verifying DB writes and cache invalidation - Subscription gate middleware (#1389) correctly blocks access after cancellation --- *Generated by CEO Planner (priority: 2)*
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
pook/compliancebot#1409
No description provided.