I cancelled my subscription, features locked 18 days later because I had forgotten — Stripe cancel_at_period_end webhook gap (PR #651 VII F4)
Caitlin (43) runs Stonecutter Inn 5-room guesthouse with 28-seat dining room in Ambleside Lake District. Wanted to downgrade Diamond->Platinum. Monday Stripe Customer Portal Cancel subscription end-of-period selected 28 days. Admin panel showed NO cancellation warning. 18 days later Tuesday morning Rooms menu gone, room QRs say "Upgrade to Diamond", guests cant order room service. Caitlin panicked "I didn t cancel Diamond outright!" Support 1 wrong theory (date misremember — current_period_end 22 May was correct). Forensic Stripe webhook log 6 May 14:32 customer.subscription.updated payload cancel_at_period_end:true cancel_at:1684680960. thMenu webhook handler SubscriptionUpdatedSchema parsed only customer + items — cancel_at_period_end/cancel_at/canceled_at ALL absent from schema. Handler took event, re-asserted tier (Diamond keeps Diamond), audit log, return 200. Cancellation-pending signal entirely ignored. 16 days later customer.subscription.deleted arrived, tier=starter, room service locked. Stripe Customer Portal shifted to cancel=end-of-period in recent years (modern UX); old cancel=immediate handler didn t see the new two-event sequence. **PR #651 batch VII F4** two-layer fix: (1) schema extend cancel_at_period_end/cancel_at/canceled_at; webhook handler writes Supabase user_profiles.cancel_at_period_end_date timestamp; reactivate nulls it. (2) admin panel banner: every page load shows "Your subscription ends on [date]. [Reactivate] [Change Plan]." Plus retention email automation 5d + 1d before period end. Caitlin panic-subscribed Platinum that morning + apologized to current guests. A week later tested fix: cancelled Platinum end-of-period, banner appeared within 30 seconds, clicked Reactivate, banner gone. Pattern: every modern Stripe Customer Portal field (cancel_at_period_end, pause/resume, pending_update, payment_action_required) must be parsed in webhook schema, surfaced in admin UI banner, and trigger retention email automation. The SubscriptionUpdatedSchema grows over time as Stripe s Portal UX evolves.