import { pbAdmin } from '$lib/server/pocketbase'; import type Stripe from 'stripe'; // Shared Stripe event handling. The real webhook (/api/webhooks/stripe) routes // through here so the DB effects are identical. export async function handleStripeEvent(event: Stripe.Event): Promise { switch (event.type) { case 'checkout.session.completed': { const session = event.data.object as Stripe.Checkout.Session; const famId = session.metadata?.famId; if (famId && session.customer) { await pbAdmin.update('fams', famId, { stripeCustomerId: String(session.customer), active: true, paymentMode: 'sub' }); } break; } case 'customer.subscription.created': case 'customer.subscription.updated': case 'customer.subscription.paused': { const sub = event.data.object as Stripe.Subscription; await setActiveFromSubscription(sub); break; } case 'customer.subscription.deleted': { const sub = event.data.object as Stripe.Subscription; const fams = await pbAdmin.getList('fams', `stripeCustomerId = '${sub.customer}'`); const fam = fams[0]; if (fam) { await pbAdmin.update('fams', fam.id, { active: false, paymentMode: 'canceled' }); } break; } } } async function setActiveFromSubscription(sub: Stripe.Subscription) { // The fam that owns this subscription — look up by the customer id stored // on the fam (set at checkout). Stripe customer id is unique per fam. const fams = await pbAdmin.getList('fams', `stripeCustomerId = '${sub.customer}'`); const fam = fams[0]; if (!fam) return; // Active only while the sub is trialing/active (not past_due/canceled/paused). const active = sub.status === 'trialing' || sub.status === 'active' || sub.status === 'past_due'; await pbAdmin.update('fams', fam.id, { active, paymentMode: 'sub' }); }