import type { ActionFunctionArgs } from "@remix-run/node"; import { authenticate } from "../shopify.server"; import { setShopTier, tierFromPlanName } from "../services/billing.server"; // Fires whenever an AppSubscription's status changes (created, activated, // cancelled, expired, frozen for non-payment, declined) — the durable, // authoritative way to keep Shop.tier in sync, since it fires even when the // merchant cancels from Shopify's own billing page rather than /app/billing. export const action = async ({ request }: ActionFunctionArgs) => { const { shop, topic, payload } = await authenticate.webhook(request); const subscription = (payload as { app_subscription?: { name?: string; status?: string } }) .app_subscription; const tier = subscription?.status === "ACTIVE" ? tierFromPlanName(subscription.name) : "free"; await setShopTier(shop, tier); console.log(`[billing] ${topic} for ${shop}: ${subscription?.name ?? "none"} (${subscription?.status}) -> tier=${tier}`); return new Response(); };