Trusted Write Path
Webhook Plan
v98 backend contract. Last updated 2026-07-09.
Current State
Payments remain inactive. The frontend may read entitlement rows after sign-in, but only a trusted backend should create or change them.
Required Tables
Apply supabase-entitlements-v97-restore-test.sql first. Then apply supabase-webhook-write-path-v98.sql for event idempotency and Stripe customer mapping.
Checkout Completed
checkout.session.completed should verify the signed event, match the Supabase user from trusted metadata, store the Stripe customer link, and grant core_ownership only after the paid session is confirmed.
Subscription Updates
customer.subscription.created, customer.subscription.updated, customer.subscription.paused, customer.subscription.resumed, and customer.subscription.deleted should maintain expansion_subscription status.
Invoice Signals
invoice.paid can confirm active subscription access. invoice.payment_failed should not instantly delete a user's core purchase, but it can move optional expansion into review or grace handling.
Guardrails
Store every Stripe event ID once, verify signatures using the webhook secret, reject browser-origin writes, and treat checkout return URLs as messaging only. Access comes from Supabase entitlement rows.